我正在尝试使用图像分类训练MLModel。我创建了一个应用程序来创建图像以用作训练数据(最后,将使用相同的过程来获取预测)。 我从AvCaptureSession获取CVPixelBuffer,将其转换为UIImage并将其保存为JPEG文件目录。后来我给它们贴标签,并在操场上用CreateML训练MLModel。自从我收集了数千张图像以来,在操场上的结果是%100。
但是,当我将此模型集成到我的应用程序中并以相同的方式进行输入时,结果会很糟糕。我得到CVPixelBuffer,将其转换为UIImage(裁剪),并将裁剪后的图像转换为CVPixelBuffer并提供给模型。我必须将UIImage转换为CVPixelBuffer,因为CoreML模型只包括CVPixelBuffer。我使用以下方法将UIImage转换为CVPixelBuffer:
func pixelBuffer(width: Int, height: Int) -> CVPixelBuffer? {
var maybePixelBuffer: CVPixelBuffer?
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue]
let status = CVPixelBufferCreate(kCFAllocatorDefault,
width,
height,
kCVPixelFormatType_32ARGB,
attrs as CFDictionary,
&maybePixelBuffer)
guard status == kCVReturnSuccess, let pixelBuffer = maybePixelBuffer else {
return nil
}
CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
guard let context = CGContext(data: pixelData,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)
else {
return nil
}
UIGraphicsPushContext(context)
context.translateBy(x: 0, y: CGFloat(height))
context.scaleBy(x: 1, y: -1)
self.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
UIGraphicsPopContext()
CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
return pixelBuffer
}
我认为我得到的结果很差,因为CoreML模型不喜欢转换后的CVPixelBuffer。
有人有什么建议吗?
答案 0 :(得分:0)
您不需要任何这些东西。让我们看一下文档:
class VNCoreMLRequest : VNImageBasedRequest
首先,VNImageBasedRequest
包含字段regionOfInterest: CGRect { get set }
,其中矩形是标准化的,并且是左下角的。 因此您不需要裁剪!只需指定ROI。
第二,VNCoreMLRequest
本身具有字段var imageCropAndScaleOption: VNImageCropAndScaleOption { get set }
,您可以在其中指定高度/宽度比与预期值不匹配时的操作方式(中心裁切,缩放以适合/填充)。