2017-04-13 2 views
4

J'essaie de faire une application de caméra simple où la caméra frontale peut détecter les visages. Cela devrait être assez simple:Caméra iOS Facetracking (Swift 3 Xcode 8)

  • Créer une classe CameraView qui hérite de UIImage et le placer dans l'interface utilisateur. Assurez-vous qu'il implémente AVCaptureVideoDataOutputSampleBufferDelegate afin de traiter les images de la caméra en temps réel.

    class CameraView: UIImageView, AVCaptureVideoDataOutputSampleBufferDelegate 
    
  • Dans un handleCamera de fonction, appelée lorsque le CameraView est instancié, la configuration d'une session AVCapture. Ajouter une entrée de la caméra.

    override init(frame: CGRect) { 
        super.init(frame:frame) 
    
        handleCamera() 
    } 
    
    func handleCamera() { 
        camera = AVCaptureDevice.defaultDevice(withDeviceType: .builtInWideAngleCamera, 
                  mediaType: AVMediaTypeVideo, position: .front) 
        session = AVCaptureSession() 
    
        // Set recovered camera as an input device for the capture session 
        do { 
         try input = AVCaptureDeviceInput(device: camera); 
        } catch _ as NSError { 
         print ("ERROR: Front camera can't be used as input") 
         input = nil 
        } 
    
        // Add the input from the camera to the capture session 
        if (session?.canAddInput(input) == true) { 
         session?.addInput(input) 
        } 
    
  • Créer une sortie. Créez une file d'attente de sortie série pour transmettre les données, qui seront ensuite traitées par AVCaptureVideoDataOutputSampleBufferDelegate (la classe elle-même dans ce cas). Ajouter une sortie à la session

    output = AVCaptureVideoDataOutput() 
    
        output?.alwaysDiscardsLateVideoFrames = true  
        outputQueue = DispatchQueue(label: "outputQueue") 
        output?.setSampleBufferDelegate(self, queue: outputQueue) 
    
        // add front camera output to the session for use and modification 
        if(session?.canAddOutput(output) == true){ 
         session?.addOutput(output) 
        } // front camera can't be used as output, not working: handle error 
        else { 
         print("ERROR: Output not viable") 
        } 
    
  • Configuration de la vue de prévisualisation de la caméra et exécuter la session

    // Setup camera preview with the session input 
        previewLayer = AVCaptureVideoPreviewLayer(session: session) 
        previewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill 
        previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait 
        previewLayer?.frame = self.bounds 
        self.layer.addSublayer(previewLayer!) 
    
        // Process the camera and run it onto the preview 
        session?.startRunning() 
    
  • dans la fonction captureOutput dirigée par le délégué, convertir le tampon d'échantillon Recieved à CIImage afin de détecter les visages. Donnez votre avis si un visage est trouvé.

    func captureOutput(_ captureOutput: AVCaptureOutput!, didDrop sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { 
    
    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) 
    let cameraImage = CIImage(cvPixelBuffer: pixelBuffer!) 
    
    
    let accuracy = [CIDetectorAccuracy: CIDetectorAccuracyHigh] 
    let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: accuracy) 
    let faces = faceDetector?.features(in: cameraImage) 
    
    for face in faces as! [CIFaceFeature] { 
    
         print("Found bounds are \(face.bounds)") 
    
         let faceBox = UIView(frame: face.bounds) 
    
         faceBox.layer.borderWidth = 3 
         faceBox.layer.borderColor = UIColor.red.cgColor 
         faceBox.backgroundColor = UIColor.clear 
         self.addSubview(faceBox) 
    
         if face.hasLeftEyePosition { 
          print("Left eye bounds are \(face.leftEyePosition)") 
         } 
    
         if face.hasRightEyePosition { 
          print("Right eye bounds are \(face.rightEyePosition)") 
         } 
        } 
    } 
    

Mon problème: je peux obtenir la caméra en cours d'exécution, mais avec la multitude de codes différents, j'ai essayé de tout sur Internet, je ne l'ai jamais été en mesure d'obtenir captureOutput pour détecter un visage. Soit l'application n'entre pas dans la fonction, soit elle se bloque à cause d'une variable qui ne fonctionne pas, le plus souvent étant que la variable sampleBuffer est nulle. Qu'est-ce que je fais de mal?

Répondre

1

Vous devez changer vos captureOutput arguments de la fonction à ce qui suit: func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!)

Votre fonction captureOutput appelle quand gouttes tampon, pas quand il reçoit de la caméra.

+0

J'ai effectivement trouvé cela avec l'aide d'un développeur iOS sur mon stage et j'ai oublié de mettre à jour la question. C'était effectivement tout ce qui manquait, merci de regarder à travers et j'espère que cela aidera quelqu'un d'autre. – KazToozs