2017-06-28 13 views
1

Visionフレームワークを使用してローカルの録画済みビデオで顔を検出しようとしています。提供されたサンプルのほとんどは、ライブカムビデオの顔を検出しています。Visionフレームワークを使用してローカルビデオの顔を追跡する

  • Vision/CoreMLフレームワークを使用して、ローカルビデオで顔検出を行い、検出された顔に実行時に矩形を配置する方法はありますか?あなたのvideoItemが
  • それに出力を追加
  • をプレイする準備ができてするため

答えて

3
  • 待機フレームごとに
  • にpingされるはずです定期的な観察者が新しいピクセルバッファを抽出し、それらを処理追加ビジョンフレームワークを使用する場合はVNImageRequestHandlerの代わりにVNSequenceRequestHandlerを使用します。

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() { 
    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 
    } 
} 
+0

私は正常に動作させるようですが、ビデオを表示するにはAVPlayerLayerを持っていたときはもうそれはありません。 – Arthuraw

+0

こんにちはアーサー:)あなたは、それが壊れたビデオを表示するとすぐに意味ですか?何が変わっているのか分かりますか? – Guig

+0

私はあなたと同じViewDidLoadを使用します(貼り付けコピー)が、このコードを追加すると動作を停止します:playerLayer = AVPlayerLayer(player:player) playerLayer.frame = CGRect(x:0、y:100、width:300、height :170) self.view.layer.addSublayer(playerLayer) – Arthuraw

関連する問題