活体检测
LivenessDetection框架可以检测图像或其部分是实时拍摄的还是来自屏幕、照片。
该框架有两个检测器:
- 莫尔条纹检测器
找到莫尔条纹干扰伪影 - 欺骗设备检测器
找到可以用于欺骗活体的设备,例如:屏幕、照片
从CocoaPods安装
-
在您的Podfile中添加以下依赖项:
pod 'LivenessDetection'
-
运行:
pod install
使用方法
- 联系Applied Recognition获取机器学习模型文件。
- 将模型文件复制到您的应用资源中。
摩尔纹检测
func detectMoireInImage(_ image: CGImage) -> Float? {
// Get the model URL from your app's resource bundle
guard let moireDetectorModelURL = Bundle.main.url(forResource: "MoireDetectorModel", withExtension: "mlmodel") else {
return nil
}
// Load the moire detector
guard let moireDetector = try? MoireDetector(modelURL: moireDetectorModelURL) else {
return nil
}
// Run the moire detection
return try? moireDetector.detectMoireInImage(cgImage)
}
伪造设备检测
func detectSpoofDevicesInImage(_ image: UIImage) -> [DetectedSpoofDevice]? {
// Get the model URL from your app's resource bundle
guard let spoofDeviceDetectorModelURL = Bundle.main.url(forResource: "SpoofDeviceDetectorModel", withExtension: "mlmodel") else {
return nil
}
// Load the spoof device detector
guard let spoofDeviceDetector = try? SpoofDeviceDetector(modelURL: spoofDeviceDetectorModelURL) else {
return nil
}
return try? spoofDeviceDetector.detectSpoofDevicesInImage(image)
}
使用检测器3的伪造检测
func detectSpoofInImage(_ image: UIImage) -> Float? {
// Get the model URL from your app's resource bundle
guard let spoofDetectorModelURL = Bundle.main.url(forResource: "SpoofDetector3Model", withExtension: "mlmodel") else {
return nil
}
// Load the spoof detector
guard let spoofDetector = try? SpoofDetector3(modelURL: spoofDetectorModelURL) else {
return nil
}
// Run the spoof detection
return try? spoofDetector.detectSpoofInImage(image)
}
注意
加载/编译模型文件可能会有一定成本。您应该在后台线程上构建探测器。除非您仅在一个图像中检测活跃度,否则您可能只想构建一次探测器,而不是为每次检测创建一个新实例。
这里是一个更完整、优化更好的示例
class LivenessDetection {
class func create(completion: Result<LivenessDetection,Error>) {
DispatchQueue.global().async {
do {
// Get the model URL from your app's resource bundle
guard let moireDetectorModelURL = Bundle.main.url(forResource: "MoireDetectorModel", withExtension: "mlmodel") else {
throw LivenessDetectionError.failedToFindMoireDetectorModelFile
}
// Load the moire detector
let moireDetector = try MoireDetector(modelURL: moireDetectorModelURL)
// Get the model URL from your app's resource bundle
guard let spoofDeviceDetectorModelURL = Bundle.main.url(forResource: "SpoofDeviceDetectorModel", withExtension: "mlmodel") else {
throw LivenessDetectionError.failedToFindSpoofDeviceDetectorModelFile
}
// Load the spoof device detector
let spoofDeviceDetector = try? SpoofDeviceDetector(modelURL: spoofDeviceDetectorModelURL)
// Get the model URL from your app's resource bundle
guard let spoofDetector3ModelURL = Bundle.main.url(forResource: "SpoofDetector3Model", withExtension: "mlmodel") else {
throw LivenessDetectionError.failedToFindSpoofDetector3ModelFile
}
// Load spoof detector 3
let spoofDetector3 = try? SpoofDetector3(modelURL: spoofDetector3ModelURL)
completion(.success(LivenessDetection(moireDetector: moireDetector, spoofDeviceDetector: spoofDeviceDetector, spoofDetector3: spoofDetector3))
} catch {
completion(.failure(error))
}
}
}
let moireDetector: MoireDetector
let spoofDeviceDetector: SpoofDeviceDetector
let spoofDetector3: SpoofDetector3
let confidenceThreshold: Float = 0.5
private init(moireDetector: MoireDetector, spoofDeviceDetector: SpoofDeviceDetector, spoofDetector3: SpoofDetector3) {
self.moireDetector = moireDetector
self.spoofDeviceDetector = spoofDeviceDetector
self.spoofDetector3 = spoofDetector3
}
func detectLivenessInImage(_ image: UIImage, completion: Result<Boolean,Error>) {
DispatchQueue.global().async {
do {
var passed: Boolean = true
let spoofDevice = try self.spoofDeviceDetector.detectSpoofDevicesInImage(image).sorted(by: { $0.confidence > $1.confidence }).first
if let device = spoofDevice, device.confidence > self.confidenceThreshold {
passed = false
}
if passed {
guard let cgImage = image.cgImage else {
throw LivenessDetectionError.failedToCreateCGImageFromUIImage
}
let moireConfidence = try self.moireDetector.detectMoireInImage(cgImage)
passed = moireConfidence > self.confidenceThreshold
}
if passed {
let spoofConfidence = try self.spoofDetector3.detectSpoofInImage(image)
passed = spoofConfidence > self.confidenceThreshold
}
completion(.success(passed))
} catch {
completion(.failure(error))
}
}
}
}
enum LivenessDetectionError: Error {
case failedToFindMoireDetectorModelFile
case failedToFindSpoofDeviceDetectorModelFile
case failedToFindSpoofDetector3ModelFile
case failedToCreateCGImageFromUIImage
}
示例类用法
LivenessDetection.create { result in
switch result {
case .success(let livenessDetection):
livenessDetection.detectLivenessInImage(image) { result in
switch result {
case .success(let passed):
NSLog("Liveness detection %@", passed ? "passed" : "failed")
case .failure(let error):
NSLog("Liveness detection failed: %@", error.localizedDescription)
}
}
case .failure(let error):
NSLog("Failed to create liveness detection instance: %@", error.localizedDescription)
}
}