美文网首页
iOS 使用 CoreImage 实现人脸检测

iOS 使用 CoreImage 实现人脸检测

作者: zackzheng | 来源:发表于2024-03-10 12:38 被阅读0次

iOS 平台有多种方式实现人脸检测,CoreImage 是其中一种简单的方式。

一、核心代码

let ciImage = xxx
let options = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: options)
let faceList = faceDetector?.features(in: ciImage)

通过 CIDetector 根据配置的 type 和 options,检测 CIImage 中是否包含人脸。
faceList 是 CIFeature 数组,可以转成 CIFaceFeature。通过访问其属性可以获取到一些检测的结果。

1.1摄像头拍照转成 CIImage

对于非由 CIImage 生成的 UIImage(比如使用 AVKit 拍照),直接访问 ciImage 会为空,所以需要自己渲染提取成 CIImage。

extension UIImage {

    var customCIImage: CIImage? {

        let systemCIImage = ciImage
        guard systemCIImage == nil else {
            return systemCIImage
        }

        let imageRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        UIGraphicsBeginImageContextWithOptions(self.size, true, 0.0)
        self.draw(in: imageRect)
        guard let newImage = UIGraphicsGetImageFromCurrentImageContext(), let cgImage = newImage.cgImage else {
            return nil
        }
        UIGraphicsEndImageContext()

        let ciImage = CIImage(cgImage: cgImage)
        return ciImage
    }
}

二、检测结果支持检测的特性

通过查看 CIFaceFeature 的定义,我们来看下支持检测出什么特性。

/** A face feature found by a CIDetector.
 All positions are relative to the original image. */
@available(iOS 5.0, *)
open class CIFaceFeature : CIFeature {

    
    
    /** coordinates of various cardinal points within a face.
     
     Note that the left eye is the eye on the left side of the face
     from the observer's perspective. It is not the left eye from
     the subject's perspective. */
    open var bounds: CGRect { get }

    open var hasLeftEyePosition: Bool { get }

    open var leftEyePosition: CGPoint { get }

    open var hasRightEyePosition: Bool { get }

    open var rightEyePosition: CGPoint { get }

    open var hasMouthPosition: Bool { get }

    open var mouthPosition: CGPoint { get }

    
    open var hasTrackingID: Bool { get }

    open var trackingID: Int32 { get }

    open var hasTrackingFrameCount: Bool { get }

    open var trackingFrameCount: Int32 { get }

    
    open var hasFaceAngle: Bool { get }

    open var faceAngle: Float { get }

    
    open var hasSmile: Bool { get }

    open var leftEyeClosed: Bool { get }

    open var rightEyeClosed: Bool { get }
}
  • 坐标
    bounds,识别到的人脸的坐标。
    注意,此处的坐标是相对于原始图像的,尺寸大小不同,且左上角为坐标原点,实际使用中需要进行转换。
  • 左右眼位置
    hasLeftEyePosition / leftEyePosition 和 hasRightEyePosition / rightEyePosition
  • 嘴巴位置
    hasMouthPosition / mouthPosition
  • Track 信息
    hasTrackingID / trackingID / hasTrackingFrameCount / trackingFrameCount
  • 脸的角度
    hasFaceAngle / faceAngle
  • 是否在微笑
    hasSmile
  • 左右眼是否闭着
    leftEyeClosed / rightEyeClosed,实际检测不大准

2.1 人脸位置计算和展示

CIImage 有个属性 extent.size,即图片的尺寸。CIFaceFeature 有个属性 bounds,即人脸所在位置。
即可转换成想要的 view 的相对坐标。

2.2 实际检测结果

- face.bounds
(593.9743650052696, 1409.8143731430173, 1052.3287265683757, 1016.9813878205605)
- face.hasLeftEyePosition
true
- face.leftEyePosition
(986.4649061334785, 2220.677064805641)
- face.hasRightEyePosition
true
- face.rightEyePosition
(1391.2080312655598, 1945.6312162347604)
- face.hasMouthPosition 
true
- face.mouthPosition
(883.7131392527372, 1705.263066681102)
- face.hasTrackingID
false
- face.trackingID
0
- face.hasTrackingFrameCount
false
- face.trackingFrameCount
0
- face.hasFaceAngle
true
- face.faceAngle
37.74833
- face.hasSmile
false
- face.leftEyeClosed
false
- face.rightEyeClosed
false

三、封装

简单封装下:

extension CIImage {
    enum FaceDetectResult {
        case noFace
        case oneFace(ratio: CGFloat, faceBounds: CGRect, imageSize: CGSize)
        case oneFaceShouldCrop(ratio: CGFloat, faceBounds: CGRect, imageSize: CGSize)
        case moreThanOneFace
    }
    var faceDetectResult: FaceDetectResult {
        let options = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
        let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: options)
        let faceList = faceDetector?.features(in: self) ?? []
        switch faceList.count {
        case 0:
            return .noFace
        case 1:
            if let face = faceList.first as? CIFaceFeature {
                let ciImageSize = ciImage.extent.size
                let faceBounds = face.bounds
                let ciImageArea = ciImageSize.width * ciImageSize.height
                let faceArea = faceBounds.width * faceBounds.height
                let ratio = faceArea / ciImageArea
                return ratio > 0.3 ? .oneFace(ratio: ratio, faceBounds: faceBounds, imageSize: ciImageSize) : .oneFaceShouldCrop(ratio: ratio, faceBounds: faceBounds, imageSize: ciImageSize)
            } else {
                return .noFace
            }
        default:
            return .moreThanOneFace
        }
    }
}

四、参考

在 iOS 上用 Core Image 实现人脸检测

相关文章

  • iOS开发之CoreImage框架使用(下)

    二、使用CoreImage实现人脸识别 人脸识别是目前非常热门的一种图像处理技术,CoreImage内置了对人脸进...

  • iOS基于CoreImage实现人脸检测(附上demo)

    本文介绍了iOS基于CoreImage的CIDetector进行人脸检测, 并附上相关demo。 demo 展示效...

  • iOS人脸识别调研

    1、系统的人脸识别 ​ 使用CoreImage里面的CIFaceFeature ​ 可以实现图片的人...

  • CoreImage 人脸检测

    首先需要导入 添加一个人脸图片 展示在viewController的self.imgView上然后 此方法还可以检...

  • iOS人脸识别(检测)

    iOS的CoreImage已经内建了人脸检测的接口,检测准确率一般,尤其是侧脸,基本上就检测不到。不过跟其他同类产...

  • CoreImage实现人脸识别-iOS

    前言 因需求需要,需要实现人脸检测功能,这次正好将这个功能整理了一下,简单的写了一个Demo。代码有点乱,不过,也...

  • 利用CoreImage实现人脸识别_iOS

    前言 因需求需要,需要实现人脸检测功能,这次正好将这个功能整理了一下,简单的写了一个Demo。代码有点乱,不过,也...

  • iOS人脸年龄|性别检测

    转载请标明来源,文章相关详细代码。本文主要介绍iOS使用习悦人脸服务实现简单的人脸年龄和性别检测。 1. 创建应用...

  • 人脸识别技术

    人脸识别技术 (一) —— 基于CoreImage实现对静止图片中人脸的识别人脸识别技术 (二) —— 基于Cor...

  • CoreImage系列二:人脸检测

    这是CoreImage系列的第二章,主要有三点 1.对静态图片进行人脸检测与打马赛克2.对摄像头录像进行人脸检测与...

网友评论

      本文标题:iOS 使用 CoreImage 实现人脸检测

      本文链接:https://www.haomeiwen.com/subject/qohpzdtx.html