【发布时间】:2017-11-11 17:24:12
【问题描述】:
Apple 的新 CoreML 框架有一个预测函数,它接受 CVPixelBuffer。为了对UIImage 进行分类,必须在两者之间进行转换。
我从 Apple 工程师那里得到的转换代码:
1 // image has been defined earlier
2
3 var pixelbuffer: CVPixelBuffer? = nil
4
5 CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_OneComponent8, nil, &pixelbuffer)
6 CVPixelBufferLockBaseAddress(pixelbuffer!, CVPixelBufferLockFlags(rawValue:0))
7
8 let colorspace = CGColorSpaceCreateDeviceGray()
9 let bitmapContext = CGContext(data: CVPixelBufferGetBaseAddress(pixelbuffer!), width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelbuffer!), space: colorspace, bitmapInfo: 0)!
10
11 bitmapContext.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
此解决方案速度很快,适用于灰度图像。必须根据图像类型进行的更改是:
- 第 5 行 |
kCVPixelFormatType_OneComponent8到另一个OSType(kCVPixelFormatType_32ARGB用于 RGB) - 第 8 行 |
colorSpace到另一个CGColorSpace(CGColorSpaceCreateDeviceRGB用于 RGB) - 第 9 行 |
bitsPerComponent为内存每个像素的位数(RGB 为 32) - 第 9 行 |
bitmapInfo到非零CGBitmapInfo属性(kCGBitmapByteOrderDefault是默认值)
【问题讨论】:
-
我认为
CVPixelBuffer只是相机图像的约定,还有ciImage,cgImage可用 -
为什么不使用视觉框架?您可以 (1) 初始化
VNCoreMLModel对象,然后使用完成处理程序初始化 (2)VNCoreMLRequest,然后使用 (3)VNImageRequestHandler- 它可以采用CIImage或文件 URL。结果是VNClassificationObservation对象的集合。当然,现在,如果您想将UIImage转换为CVPixelBuffer- 您真的没有在任何地方在您的问题中没有问题:-) - 你可以简单地在互联网上搜索并找到这个:gist.github.com/cieslak/743f9321834c5a40597afa1634a48343 -
@dfd 是的,所以我确实想将
UIImage转换为CVPixelBuffer以使用 CoreML 模型,但我请 WWDC 的 Apple 工程师解决了这个问题上面的代码。鉴于会议上的其他几个人也遇到了同样的问题,我想我会分享一个比 github 解决方案更简单地实现其目的的解决方案。不过感谢您的建议! -
@Ryan:您是在问问题还是想分享解决方案?在后一种情况下,您应该将其发布为一个自我回答的问题:stackoverflow.com/help/self-answer。
-
+1 给 Martin R,请将问题的后半部分移到问题的答案中,让其他人也能回答!
标签: swift uiimage cvpixelbuffer coreml