视频中有脸吗?从视频中提取所有帧,并输入到Vision中

时间:2019-12-01 18:47:43

标签: swift vision

阅读了很多有关此的教程,但尚未找到可以轻松实现到XCode11中的解决方案。

我想从photoLibrary中获取视频,然后简单地写一个布尔值来说明视频在任何时间点是否都存在人脸。

有没有简单的方法可以写这个?我的想象是,从照相馆加载视频,使用AVFoundations播放,然后使用观察者将视频逐帧输出到视觉中,使用VNSequenceHandler进行面部识别。

有人可以帮忙吗?

谢谢! 詹姆斯

应评论者的要求,这是我尝试做的事情:

import UIKit
import AVFoundation
import CoreML
import Vision

class ViewController: UIViewController {
  var player: AVPlayer!
  var videoOutput: AVPlayerItemVideoOutput?

  override func viewDidLoad() {
    super.viewDidLoad()
    let URL = NSURL(fileURLWithPath: "videplayback.mp4")
    let player = AVPlayer(URL: URL)
    player.play()

    player.currentItem?.addObserver(
      self,
      forKeyPath: #keyPath(AVPlayerItem.status),
      options: [.initial, .old, .new],
      context: nil)
    player.addPeriodicTimeObserver(
      forInterval: CMTime(value: 1, timescale: 30),
      queue: DispatchQueue(label: "videoProcessing", qos: .background),
      using: { time in
        self.Facerecognition()
    })
    self.player = player
  }

  override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard let keyPath = keyPath, let item = object as? AVPlayerItem
      else { return }

    switch keyPath {
    case #keyPath(AVPlayerItem.status):
      if item.status == .readyToPlay {
        self.setUpOutput()
      }
      break
    default: break
    }
  }

  func setUpOutput() {
    guard self.videoOutput == nil else { return }
    let videoItem = player.currentItem!
    if videoItem.status != AVPlayerItem.Status.readyToPlay {
      return
    }

    let pixelBuffAttributes = [
      kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
      ] as [String: Any]

    let videoOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: pixelBuffAttributes)
    videoItem.add(videoOutput)
    self.videoOutput = videoOutput
  }

  func getNewFrame() -> CVPixelBuffer? {
    guard let videoOutput = videoOutput, let currentItem = player.currentItem else { return nil }
    let time = currentItem.currentTime()
    if !videoOutput.hasNewPixelBuffer(forItemTime: time) { return nil }
    guard let buffer = videoOutput.copyPixelBuffer(forItemTime: time, itemTimeForDisplay: nil)
      else { return nil }
    return buffer
  }

  func Facerecognition() {
    guard let buffer = getNewFrame() else { return }
    let visionSequenceHandler = VNSequenceRequestHandler()

    let request = VNTrackObjectRequest(detectedObjectObservation: lastObservation, completionHandler: self.handleVisionRequestUpdate)

    request.trackingLevel = .accurate

    do {
        try self.visionSequenceHandler.perform([request], on: buffer)
    } catch {
        print("Throws: \(error)")
    }

            }

        }

0 个答案:

没有答案