AVFoundation 是一個能夠用來使用和建立基於時間的視聽媒體數據的框架。AVFoundation 的構建考慮到了目前的硬件環境和應用程序,其設計過程高度依賴多線程機制。充分利用了多核硬件的優點並大量使用block和GCD機制,將複雜的計算機進程放到了後臺線程運行。會自動提供硬件加速操做,確保在大部分設備上應用程序能以最佳性能運行。算法
若是你有更好的建議或者對這篇文章有不滿的地方, 請聯繫我, 我會進行修改, 聯繫我時,請備註使用AVFoundatio實現動態人臉識別(技術交流羣:656315826) 最後: 祝你們學習愉快~謝謝~
1 負責把捕捉的音頻視頻數據輸出到輸出設備中。 2 一個AVCaptureSession能夠有多個輸入或輸出。 3是鏈接AVCaptureInput和AVCaptureOutput的橋樑,它協調input到output之間傳輸數據。 4 它有startRunning和stopRunning兩種方法來開啓會話和結束會話。 5 每一個session稱之爲一個會話,也就是在應用運行過程當中若是你須要改變會話的一些配置(例如:切換攝像頭),此時須要先開啓配置,配置完成以後再提交配置。
輸出設備數組
//建立原數據的輸出對象 let metadataOutput = AVCaptureMetadataOutput() //設置代理監聽輸出對象輸出的數據,在主線程中刷新 metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) //告訴輸出對象要輸出什麼樣的數據,識別人臉, 最多可識別10張人臉 metadataOutput.metadataObjectTypes = [.face]
切換攝像頭session
@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
處理掃描結果多線程
實現AVCaptureMetadataOutputObjectsDelegate該協議的協議方法(只有一個方法) AVMetadataFaceObject介紹app
獲取預覽圖層的人臉數組框架
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 }
根據人臉位置添加紅框ide
設置紅框的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) }
至此, 動態的人臉識別就完成了, 會在人臉位置增長紅框顯示, 而且紅框會根據人臉的位置動態的, 實時的調整
下面就快拿起你的相機測試吧
想要獲取案例源碼能夠加我技術交流羣:656315826 最近我在研究這一塊,若是你有更好的建議或者對這篇文章有不滿的地方, 請聯繫我, 我會進行修改,共同窗習進步。
祝你們學習愉快