AVFoundation實現動態人臉識別

簡介

AVFoundation 是一個能夠用來使用和建立基於時間的視聽媒體數據的框架。AVFoundation 的構建考慮到了目前的硬件環境和應用程序,其設計過程高度依賴多線程機制。充分利用了多核硬件的優點並大量使用block和GCD機制,將複雜的計算機進程放到了後臺線程運行。會自動提供硬件加速操做,確保在大部分設備上應用程序能以最佳性能運行。算法

若是你有更好的建議或者對這篇文章有不滿的地方, 請聯繫我, 我會進行修改,
聯繫我時,請備註使用AVFoundatio實現動態人臉識別(技術交流羣:656315826)
最後:
祝你們學習愉快~謝謝~

介紹一些人臉識別的方式

  1. CoreImage靜態人臉識別, 可識別照片, 圖像等
  2. Face++是新一代雲端視覺服務平臺,提供一整套世界領先的人臉檢測,人臉識別,面部分析的視覺技術服務
  3. OpenCV由一系列 C 函數和少許 C++ 類構成, 實現了圖像處理和計算機視覺方面的不少通用算法
  4. Vision 是 Apple 在 WWDC 2017 伴隨iOS 11推出的基於CoreML的圖像識別框架
  5. AVFoundation能夠用來使用和建立基於時間的視聽媒體的框架,今天咱們使用的人臉識別方式也是使用AVFoundation框架

對關鍵類的簡單介紹

  1. AVCaptureDevice 表明了輸入設備,例如攝像頭與麥克風。咱們能夠從這個類中獲取手機硬件的照相機、聲音傳感器等。
  2. AVCaptureDeviceInput:設備輸入數據管理對象,能夠根據AVCaptureDevice建立對應的對象
  3. AVCaptureOutput表明輸出數據,輸出的能夠是圖片或者視頻
  4. AVCaptureSession: 媒體(音、視頻)捕捉會話
1 負責把捕捉的音頻視頻數據輸出到輸出設備中。
2 一個AVCaptureSession能夠有多個輸入或輸出。
3是鏈接AVCaptureInput和AVCaptureOutput的橋樑,它協調input到output之間傳輸數據。
4 它有startRunning和stopRunning兩種方法來開啓會話和結束會話。
5 每一個session稱之爲一個會話,也就是在應用運行過程當中若是你須要改變會話的一些配置(例如:切換攝像頭),此時須要先開啓配置,配置完成以後再提交配置。
  1. AVCaptureVideoPreviewLayer: 圖片預覽層咱們的照片以及視頻是如何顯示在手機上的呢?那就是經過把這個對象添加到UIView的layer上的

添加掃描設備

  • 獲取設備(攝像頭)
  • 建立輸入設備
  • 建立掃描輸出
  • 建立捕捉回話

輸出設備數組

  • 這裏使用AVCaptureMetadataOutput, 能夠掃描人臉, 二維碼, 條形碼等信息
  • 必須設置代理, 不然獲取不到掃描結果
  • 須要設置要輸出什麼樣的數據: face(人臉), qr(二維碼)等等
//建立原數據的輸出對象
let metadataOutput = AVCaptureMetadataOutput()

//設置代理監聽輸出對象輸出的數據,在主線程中刷新
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)

//告訴輸出對象要輸出什麼樣的數據,識別人臉, 最多可識別10張人臉
metadataOutput.metadataObjectTypes = [.face]

切換攝像頭session

  • 獲取當前攝像頭方向
  • 建立新的輸入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介紹app

  1. faceID: 人臉的惟一標識
  • 掃描出來的每個人, 有不一樣的faceID
  • 同一我的, 不一樣的狀態下(搖頭, 歪頭, 擡頭等), 都會有不一樣faceID
  1. hasRollAngle: 是否有傾斜角,側傾角(左右歪頭)(BOOL類型)
  2. rollAngle: 傾斜角,側傾角的角度(CGFloat類型)
  3. hasYawAngle: 是否有偏轉角(左右搖頭)
  4. 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
}

根據人臉位置添加紅框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 最近我在研究這一塊,若是你有更好的建議或者對這篇文章有不滿的地方, 請聯繫我, 我會進行修改,共同窗習進步。

祝你們學習愉快

人臉識別

相關文章
相關標籤/搜索