使用 Vision 框架跟踪本地视频中的人脸 [关闭]
Posted
技术标签:
【中文标题】使用 Vision 框架跟踪本地视频中的人脸 [关闭]【英文标题】:Track faces in Local video using Vision framework [closed] 【发布时间】:2017-12-02 10:52:22 【问题描述】:我正在尝试使用 Vision 框架检测本地录制视频中的人脸。提供的大多数示例都是在 Live cam 视频中检测人脸。
如何在本地视频中进行人脸检测,并在运行时使用 Vision/CoreML 框架在检测到的人脸中放置一个矩形?【问题讨论】:
【参考方案1】: 等待您的 videoItem 准备好播放 向其添加输出 添加一个周期性的观察者,它应该在每一帧都被 ping 通 提取新的像素缓冲区并根据需要在 Vision / CoreML 中处理它们: 如果您使用视觉框架,您希望使用VNSequenceRequestHandler
而不是VNImageRequestHandler
。
.
import UIKit
import AVFoundation
import CoreML
import Vision
class ViewController: UIViewController
var player: AVPlayer!
var videoOutput: AVPlayerItemVideoOutput?
override func viewDidLoad()
super.viewDidLoad()
let player = AVPlayer(url: localURL)
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.doThingsWithFaces()
)
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 != AVPlayerItemStatus.readyToPlay
// see https://forums.developer.apple.com/thread/27589#128476
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 doThingsWithFaces()
guard let buffer = getNewFrame() else return
// some CoreML / Vision things on that.
// There are numerous examples with this
【讨论】:
我似乎让它工作得很好,但是当我有一个 AVPlayerLayer 来显示视频时,它就不再显示了。 嗨亚瑟 :) 你的意思是一旦你显示它打破的视频?你知道什么时候事情会变得奇怪吗? 我使用与您相同的 ViewDidLoad(复制粘贴),但是当我添加此代码时它停止工作: playerLayer = AVPlayerLayer(player: player) playerLayer.frame = CGRect(x: 0, y: 100 , 宽度: 300, 高度: 170) self.view.layer.addSublayer(playerLayer) 当我评论 player.currentItem?.addObserver 方法时,它会显示 AVPlayerLayer,但是,我没有得到观察者:D 这是因为这个例子一遍又一遍地添加了videoOutput。尝试 switch keyPath case #keyPath(AVPlayerItem.status): if item.status == .readyToPlay && self.videoOutput == nil self.setUpOutput() break以上是关于使用 Vision 框架跟踪本地视频中的人脸 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
使用 Vision 和 AVFoundation 框架从实时摄像头(而非静态图像)进行实时人脸检测