###簡介 AVFoundation 是一個能夠用來使用和建立基於時間的視聽媒體數據的框架。AVFoundation 的構建考慮到了目前的硬件環境和應用程序,其設計過程高度依賴多線程機制。充分利用了多核硬件的優點並大量使用block和GCD機制,將複雜的計算機進程放到了後臺線程運行。會自動提供硬件加速操做,確保在大部分設備上應用程序能以最佳性能運行。算法
(技術交流羣:923910776)數組
###介紹一些人臉識別的方式bash
###對關鍵類的簡單介紹session
1 負責把捕捉的音頻視頻數據輸出到輸出設備中。
2 一個AVCaptureSession能夠有多個輸入或輸出。
3是鏈接AVCaptureInput和AVCaptureOutput的橋樑,它協調input到output之間傳輸數據。
4 它有startRunning和stopRunning兩種方法來開啓會話和結束會話。
5 每一個session稱之爲一個會話,也就是在應用運行過程當中若是你須要改變會話的一些配置(例如:切換攝像頭),此時須要先開啓配置,配置完成以後再提交配置。
複製代碼
###添加掃描設備多線程
輸出設備app
//建立原數據的輸出對象
let metadataOutput = AVCaptureMetadataOutput()
//設置代理監聽輸出對象輸出的數據,在主線程中刷新
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
//告訴輸出對象要輸出什麼樣的數據,識別人臉, 最多可識別10張人臉
metadataOutput.metadataObjectTypes = [.face]
複製代碼
切換攝像頭框架
@IBAction func switchCameraAction(_ sender: Any) {
//執行轉場動畫
let anima = CATransition()
anima.type = "oglFlip"
anima.subtype = "fromLeft"
anima.duration = 0.5
view.layer.add(anima, forKey: nil)
//獲取當前攝像頭
guard let deviceIn = deviceInput else { return }
let position: AVCaptureDevice.Position = deviceIn.device.position == .back ? .front : .back
//建立新的input
let deviceSession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: position)
guard let newDevice = deviceSession.devices.filter({ $0.position == position }).first else { return }
guard let newVideoInput = try? AVCaptureDeviceInput(device: newDevice) else { return }
//移除舊輸入,添加新輸入
//設備加鎖
session.beginConfiguration()
//移除舊設備
session.removeInput(deviceIn)
//添加新設備
session.addInput(newVideoInput)
//設備解鎖
session.commitConfiguration()
//保存最新輸入
deviceInput = newVideoInput
複製代碼
處理掃描結果ide
實現AVCaptureMetadataOutputObjectsDelegate該協議的協議方法(只有一個方法) AVMetadataFaceObject介紹函數
獲取預覽圖層的人臉數組性能
fileprivate func transformedFaces(faceObjs: [AVMetadataObject]) -> [AVMetadataObject] {
var faceArr = [AVMetadataObject]()
for face in faceObjs {
//將掃描的人臉對象轉成在預覽圖層的人臉對象(主要是座標的轉換)
if let transFace = previewLayer.transformedMetadataObject(for: face){
faceArr.append(transFace)
}
}
return faceArr
}
複製代碼
根據人臉位置添加紅框
設置紅框的frame
faceLayer?.frame = face.bounds
複製代碼
根據偏轉角和傾斜角的角度獲取CATransform3D
fileprivate func transformDegress(yawAngle: CGFloat) -> CATransform3D {
let yaw = degreesToRadians(degress: yawAngle)
//圍繞Y軸旋轉
let yawTran = CATransform3DMakeRotation(yaw, 0, -1, 0)
//紅框旋轉問題
return CATransform3DConcat(yawTran, CATransform3DIdentity)
}
//處理偏轉角問題
fileprivate func transformDegress(rollAngle: CGFloat) -> CATransform3D {
let roll = degreesToRadians(degress: rollAngle)
//圍繞Z軸旋轉
return CATransform3DMakeRotation(roll, 0, 0, 1)
}
//角度轉換
fileprivate func degreesToRadians(degress: CGFloat) -> CGFloat{
return degress * CGFloat(Double.pi) / 180
}
複製代碼
根據有無偏轉角和傾斜角旋轉紅框
//設置偏轉角(左右搖頭)
if face.hasYawAngle{
let tranform3D = transformDegress(yawAngle: face.yawAngle)
//矩陣處理
faceLayer?.transform = CATransform3DConcat(faceLayer!.transform, tranform3D)
}
//設置傾斜角,側傾角(左右歪頭)
if face.hasRollAngle{
let tranform3D = transformDegress(rollAngle: face.rollAngle)
//矩陣處理
faceLayer?.transform = CATransform3DConcat(faceLayer!.transform, tranform3D)
}
複製代碼
至此, 動態的人臉識別就完成了, 會在人臉位置增長紅框顯示, 而且紅框會根據人臉的位置動態的, 實時的調整
下面就快拿起你的相機測試吧