这几天用coreml和vision写了个颜色识别项目,训练后的coreml的准确率达到了99.5%,但是实际上使用的时候效果并不理想。
因为是将相机的CVPixelBuffer导入进去识别的,第一反应是CVPixelBuffer和真实的照片颜色有出入,去细究了下:当将 CVPixelBuffer 转换为真实的照片(比如 UIImage),系统会根据特定的颜色空间和配置信息对像素数据进行解释和显示。这个过程应该是一个准确的转换,不会引入颜色误差。
排除了这一问题,接下来考虑的是相机的配置问题:对比度、饱和度这些,但是发现也不是。。。。
最后将真实照片放入到CoreML中预测的时候,效果竟然出乎意料的好,才发现是CoreML 和 Vision的confident有出入,至于为什么有出入,暂时还没找到原因。希望有大佬看到了能解惑,谢谢了。
至此,我直接用CoreML处理图像获得结果。
具体代码如下:
// 使用
if let restoredImage = self.convertCVPixelBufferToUIImage(pixelBuffer: currentFrame.capturedImage) {
// 在这里使用还原的 UIImage 对象
let ciImage = CIImage(image: restoredImage)
let model = MyImageClassifier2() // MyModel为我们训练好的CoreML模型
let output = try? model.prediction(image: currentFrame.capturedImage) // 使用CoreML模型进行预测
if let result = output?.target { // 输出预测结果
print(result)
}
} else {
print("无法将 CVPixelBuffer 转换为 UIImage")
}
//CVPixelBuffer转换uiimage
func convertCVPixelBufferToUIImage(pixelBuffer: CVPixelBuffer) -> UIImage? {
let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
let context = CIContext()
if let cgImage = context.createCGImage(ciImage, from: ciImage.extent) {
return UIImage(cgImage: cgImage)
}
return nil
}
为了提高准确度,可以将CVPixelBuffer转换为CgImage后裁剪指定区域:
// 截取指定区域的图像
let originalImage = CIImage(cvPixelBuffer: currentFrame.capturedImage)
let context = CIContext()
// 定义要截取的区域
for touch in touches {
let location = touch.location(in: self.view)
let regionOfInterest = CGRect(x: location.x - 25, y: location.y - 25, width: 50, height: 50)
// 使用 Core Graphics 截取指定区域的图像
if let cgImage = context.createCGImage(originalImage, from: regionOfInterest) {
// let croppedImage = UIImage(cgImage: cgImage)
// 现在 cgImage 就是截取后的图像,可以在这里使用它
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([request])
}
}