iOS利用CoreImage实现人脸识别详解

2020-01-20 13:13:48刘景俊

再次运行app,应该会看到人的面部周围会有一个框。OK,你已经成功使用Core Image识别出了人脸。

coreimage,人脸识别,ios,demo

但是有的童鞋在使用了上面的代码运行后可能会出现方框不存在(即没有识别人脸)这种情况,这是由于忘记关闭Auto Layout以及Size Classes了。 选中storyBoard中的ViewController,选中view下的imageView。然后在右边的面板中的第一个选项卡中找到use Auto Layout ,将前面的✔️去掉就可以了

coreimage,人脸识别,ios,demo

经过上面的设置后我们再次运行App,就会看到图三出现的效果了。

构建一个人脸识别的相机应用

想象一下你有一个用来照相的相机app,照完相后你想运行一下人脸识别来检测一下是否存在人脸。若存在一些人脸,你也许想用一些标签来对这些照片进行分类。我们不会构建一个保存照片后再处理的app,而是一个实时的相机app,因此需要整合一下UIImagePicker类,在照完相时立刻进行人脸识别。

在开始工程中已经创建好了CameraViewController类,使用如下代码实现相机的功能:


class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
 @IBOutlet var imageView: UIImageView!
 let imagePicker = UIImagePickerController()

 override func viewDidLoad() {
  super.viewDidLoad()
  imagePicker.delegate = self
 }

 @IBAction func takePhoto(_ sender: AnyObject) {

  if !UIImagePickerController.isSourceTypeAvailable(.camera) {
   return
  }

  imagePicker.allowsEditing = false
  imagePicker.sourceType = .camera

  present(imagePicker, animated: true, completion: nil)
 }

 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

  if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
   imageView.contentMode = .scaleAspectFit
   imageView.image = pickedImage
  }

  dismiss(animated: true, completion: nil)
  self.detect()
 }

 func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
  dismiss(animated: true, completion: nil)
 }
}

前面几行设置UIImagePicker委托为当前视图类,在didFinishPickingMediaWithInfo方法(UIImagePicker的委托方法)中设置imageView为在方法中所选择的图像,接着返回上一视图调用detect函数。

还没有实现detect函数,插入下面代码并分析一下:


func detect() {
 let imageOptions = NSDictionary(object: NSNumber(value: 5) as NSNumber, forKey: CIDetectorImageOrientation as NSString)
 let personciImage = CIImage(cgImage: imageView.image!.cgImage!)
 let accuracy = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
 let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: accuracy)
 let faces = faceDetector?.features(in: personciImage, options: imageOptions as? [String : AnyObject])

 if let face = faces?.first as? CIFaceFeature {
  print("found bounds are (face.bounds)")

  let alert = UIAlertController(title: "提示", message: "检测到了人脸", preferredStyle: UIAlertControllerStyle.alert)
  alert.addAction(UIAlertAction(title: "确定", style: UIAlertActionStyle.default, handler: nil))
  self.present(alert, animated: true, completion: nil)

  if face.hasSmile {
   print("face is smiling");
  }

  if face.hasLeftEyePosition {
   print("左眼的位置: (face.leftEyePosition)")
  }

  if face.hasRightEyePosition {
   print("右眼的位置: (face.rightEyePosition)")
  }
 } else {
  let alert = UIAlertController(title: "提示", message: "未检测到人脸", preferredStyle: UIAlertControllerStyle.alert)
  alert.addAction(UIAlertAction(title: "确定", style: UIAlertActionStyle.default, handler: nil))
  self.present(alert, animated: true, completion: nil)
 }
}