簡介
AVFoundation 是一個可以用來使用和創建基于時間的視聽媒體數據的框架。AVFoundation 的構建考慮到了目前的硬件環境和應用程序,其設計過程高度依賴多線程機制。充分利用了多核硬件的優勢并大量使用block和GCD機制,將復雜的計算機進程放到了后臺線程運行。會自動提供硬件加速操作,確保在大部分設備上應用程序能以最佳性能運行。
如果你有更好的建議或者對這篇文章有不滿的地方, 請聯系我, 我會進行修改,
聯系我時,請備注使用AVFoundatio實現動態人臉識別(技術交流群:551346706)
最后:
祝大家學習愉快~謝謝~
介紹一些人臉識別的方式
- CoreImage靜態人臉識別, 可識別照片, 圖像等
- Face++是新一代云端視覺服務平臺,提供一整套世界領先的人臉檢測,人臉識別,面部分析的視覺技術服務
- OpenCV由一系列 C 函數和少量 C++ 類構成, 實現了圖像處理和計算機視覺方面的很多通用算法
- Vision 是 Apple 在 WWDC 2017 伴隨iOS 11推出的基于CoreML的圖像識別框架
- AVFoundation可以用來使用和創建基于時間的視聽媒體的框架,今天我們使用的人臉識別方式也是使用AVFoundation框架
對關鍵類的簡單介紹
- AVCaptureDevice 代表了輸入設備,例如攝像頭與麥克風。我們可以從這個類中獲取手機硬件的照相機、聲音傳感器等。
- AVCaptureDeviceInput:設備輸入數據管理對象,可以根據AVCaptureDevice創建對應的對象
- AVCaptureOutput代表輸出數據,輸出的可以是圖片或者視頻
- AVCaptureSession: 媒體(音、視頻)捕捉會話
1 負責把捕捉的音頻視頻數據輸出到輸出設備中。
2 一個AVCaptureSession可以有多個輸入或輸出。
3是連接AVCaptureInput和AVCaptureOutput的橋梁,它協調input到output之間傳輸數據。
4 它有startRunning和stopRunning兩種方法來開啟會話和結束會話。
5 每個session稱之為一個會話,也就是在應用運行過程中如果你需要改變會話的一些配置(例如:切換攝像頭),此時需要先開啟配置,配置完成之后再提交配置。
- AVCaptureVideoPreviewLayer: 圖片預覽層我們的照片以及視頻是如何顯示在手機上的呢?那就是通過把這個對象添加到UIView的layer上的
添加掃描設備
- 獲取設備(攝像頭)
- 創建輸入設備
- 創建掃描輸出
- 創建捕捉回話
輸出設備
- 這里使用AVCaptureMetadataOutput, 可以掃描人臉, 二維碼, 條形碼等信息
- 必須設置代理, 否則獲取不到掃描結果
- 需要設置要輸出什么樣的數據: face(人臉), qr(二維碼)等等
//創建原數據的輸出對象
let metadataOutput = AVCaptureMetadataOutput()
//設置代理監聽輸出對象輸出的數據,在主線程中刷新
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
//告訴輸出對象要輸出什么樣的數據,識別人臉, 最多可識別10張人臉
metadataOutput.metadataObjectTypes = [.face]
切換攝像頭
- 獲取當前攝像頭方向
- 創建新的輸入input
- 移除舊輸入capture, 添加新的輸入capture
- 具體代碼如下:
@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介紹
- faceID: 人臉的唯一標識
- 掃描出來的每一個人, 有不同的faceID
- 同一個人, 不同的狀態下(搖頭, 歪頭, 抬頭等), 都會有不同faceID
- hasRollAngle: 是否有傾斜角,側傾角(左右歪頭)(BOOL類型)
- rollAngle: 傾斜角,側傾角的角度(CGFloat類型)
- hasYawAngle: 是否有偏轉角(左右搖頭)
- yawAngle: 偏轉角角度
獲取預覽圖層的人臉數組
- 遍歷掃描的人臉數組, 轉換成在預覽圖層的人臉數組
- 主要是人臉在圖層的左邊的轉換
- 返回轉換后的新的數組
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)
}
至此, 動態的人臉識別就完成了, 會在人臉位置增加紅框顯示, 并且紅框會根據人臉的位置動態的, 實時的調整
下面就快拿起你的相機測試吧
項目代碼獲取
關注微信公眾號:iOSSir,每日更新蘋果資訊、技術干貨!
公眾號二維碼.jpg
祝大家學習愉快
人臉識別