机器学习套件 iOS 人脸检测错误
ML Kit iOS Face Detection Bug
我一直在尝试使用 Google ML Face Detection iOS Library
但是有一个问题是它不能与前置摄像头一起使用,只有当我在 phone 上使用后置摄像头时它才能检测到人脸。我打印出方向,正面和背面的一切都匹配。它似乎适用于我的 iPhone X 的正面和背面,但当我在 iPhone 11 和 iPhone X max 上测试它时,它只适用于后置摄像头。我不确定是什么导致了这种不一致。我使用的代码如下,注意所有传入photoVerification函数的图片都是运行先通过fixedOrientation函数保证一致性:
func photoVerification(image: UIImage?) {
guard let imageFace = image else { return }
//Enhanced Face Detection
let options = FaceDetectorOptions()
options.performanceMode = .accurate
//Initialize face detector with given options
let faceDetector = FaceDetector.faceDetector(options: options)
// Initialize a VisionImage object with the given UIImage.
let visionImage = VisionImage(image: imageFace)
visionImage.orientation = imageFace.imageOrientation
print("$$The Images Orientation is: ",imageFace.imageOrientation.rawValue)
faceDetector.process(visionImage) { faces, error in
guard error == nil, let faces = faces, !faces.isEmpty else {
// [START_EXCLUDE]
let errorString = error?.localizedDescription ?? "NO Results Possible"
print("Error: ",errorString)
//No face detected provide error on image
print("No face detected!")
self.userVerified = false
self.addVerifiedTag(isVerified: false)
// [END_EXCLUDE]
return
}
// Faces detected
// [START_EXCLUDE]
//Face Has been detected Offer Verified Tag to user
print("Face detected!")
self.userVerified = true
self.addVerifiedTag(isVerified: true)
}
}
func fixedOrientation(image:UIImage) -> UIImage?{
guard image.imageOrientation != .up else{
//Orientation is correct
return image
}
guard let cgImage = image.cgImage else{
//CGimage not available
return nil
}
guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else{
return nil
}
var transform:CGAffineTransform = CGAffineTransform.identity
switch image.imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: image.size.height)
transform = transform.rotated(by: CGFloat.pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2.0)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: image.size.height)
transform = transform.rotated(by: CGFloat.pi / -2.0)
case .up, .upMirrored:
break
@unknown default:
break
}
// Flip image one more time if needed to, this is to prevent flipped image
switch image.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: image.size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .up, .down, .left, .right:
break
@unknown default:
break
}
ctx.concatenate(transform)
switch image.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width))
default:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
break
}
guard let newCGImage = ctx.makeImage() else { return nil }
return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
}
您 post 中的 Google ML Kit Face Detection SDK 适用于 iPhone 11 上的前置和后置摄像头(我的是 运行 iOS 13.4,我使用 Xcode 11.6)。您可以查看 iOS 快速入门示例应用程序(在 Swift 和 Objective-C 中),它演示了如何使用前置和后置摄像头拍摄照片(或预览实时视频)进行面部检测(和其他功能):
https://github.com/googlesamples/mlkit/tree/master/ios/quickstarts/vision
我一直在尝试使用 Google ML Face Detection iOS Library 但是有一个问题是它不能与前置摄像头一起使用,只有当我在 phone 上使用后置摄像头时它才能检测到人脸。我打印出方向,正面和背面的一切都匹配。它似乎适用于我的 iPhone X 的正面和背面,但当我在 iPhone 11 和 iPhone X max 上测试它时,它只适用于后置摄像头。我不确定是什么导致了这种不一致。我使用的代码如下,注意所有传入photoVerification函数的图片都是运行先通过fixedOrientation函数保证一致性:
func photoVerification(image: UIImage?) {
guard let imageFace = image else { return }
//Enhanced Face Detection
let options = FaceDetectorOptions()
options.performanceMode = .accurate
//Initialize face detector with given options
let faceDetector = FaceDetector.faceDetector(options: options)
// Initialize a VisionImage object with the given UIImage.
let visionImage = VisionImage(image: imageFace)
visionImage.orientation = imageFace.imageOrientation
print("$$The Images Orientation is: ",imageFace.imageOrientation.rawValue)
faceDetector.process(visionImage) { faces, error in
guard error == nil, let faces = faces, !faces.isEmpty else {
// [START_EXCLUDE]
let errorString = error?.localizedDescription ?? "NO Results Possible"
print("Error: ",errorString)
//No face detected provide error on image
print("No face detected!")
self.userVerified = false
self.addVerifiedTag(isVerified: false)
// [END_EXCLUDE]
return
}
// Faces detected
// [START_EXCLUDE]
//Face Has been detected Offer Verified Tag to user
print("Face detected!")
self.userVerified = true
self.addVerifiedTag(isVerified: true)
}
}
func fixedOrientation(image:UIImage) -> UIImage?{
guard image.imageOrientation != .up else{
//Orientation is correct
return image
}
guard let cgImage = image.cgImage else{
//CGimage not available
return nil
}
guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else{
return nil
}
var transform:CGAffineTransform = CGAffineTransform.identity
switch image.imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: image.size.height)
transform = transform.rotated(by: CGFloat.pi)
case .left, .leftMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2.0)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: image.size.height)
transform = transform.rotated(by: CGFloat.pi / -2.0)
case .up, .upMirrored:
break
@unknown default:
break
}
// Flip image one more time if needed to, this is to prevent flipped image
switch image.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: image.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: image.size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .up, .down, .left, .right:
break
@unknown default:
break
}
ctx.concatenate(transform)
switch image.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: image.size.height, height: image.size.width))
default:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
break
}
guard let newCGImage = ctx.makeImage() else { return nil }
return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
}
您 post 中的 Google ML Kit Face Detection SDK 适用于 iPhone 11 上的前置和后置摄像头(我的是 运行 iOS 13.4,我使用 Xcode 11.6)。您可以查看 iOS 快速入门示例应用程序(在 Swift 和 Objective-C 中),它演示了如何使用前置和后置摄像头拍摄照片(或预览实时视频)进行面部检测(和其他功能):
https://github.com/googlesamples/mlkit/tree/master/ios/quickstarts/vision