【问题标题】:VNDetectFaceRectanglesRequest detecting of the faceVNDetectFaceRectanglesRequest 检测人脸
【发布时间】:2017-11-18 09:09:23
【问题描述】:

我正在使用Vision 框架来处理图像。我正在使用的函数运行良好,并且不会在完成处理程序中返回任何错误,但结果为空。

这是我的功能:

 func recognizeImage() {
        let request = VNDetectFaceRectanglesRequest { (res: VNRequest, error: Error?) in
            print("Reuslt : \(res.accessibilityActivationPoint)")
        }

        if let cgContet = image.image.cgImage  {
            let handler = VNImageRequestHandler(cgImage: cgContet)
            try? handler.perform([request])
        }
    }

函数的结果是:

Reuslt : (0.0, 0.0)

【问题讨论】:

  • 这里到底要问什么?
  • @rambossa 为什么使用的函数返回空结果而没有任何错误

标签: swift swift4 apple-vision


【解决方案1】:

如果你想检测人脸并在每个人脸上画一个矩形,试试这个:

let request=VNDetectFaceRectanglesRequest{request, error in
    var final_image=UIImage(named: image_to_process)

    if let results=request.results as? [VNFaceObservation]{
        print(results.count, "faces found")
        for face_obs in results{
          //draw original image
          UIGraphicsBeginImageContextWithOptions(final_image.size, false, 1.0)
          final_image.draw(in: CGRect(x: 0, y: 0, width: final_image.size.width, height: final_image.size.height))

          //get face rect
          var rect=face_obs.boundingBox
          let tf=CGAffineTransform.init(scaleX: 1, y: -1).translatedBy(x: 0, y: -final_image.size.height)
          let ts=CGAffineTransform.identity.scaledBy(x: final_image.size.width, y: final_image.size.height)
          let converted_rect=rect.applying(ts).applying(tf)    

          //draw face rect on image
          let c=UIGraphicsGetCurrentContext()!
          c.setStrokeColor(UIColor.red.cgColor)
          c.setLineWidth(0.01*final_image.size.width)
          c.stroke(converted_rect)

          //get result image
          let result=UIGraphicsGetImageFromCurrentImageContext()
          UIGraphicsEndImageContext()

          final_image=result!
        }
    }

    //display final image
    DispatchQueue.main.async{
        self.image_view.image=final_image
    }
}


guard let ciimage=CIImage(image:image_to_process) else{
  fatalError("couldn't convert uiimage to ciimage")
}

let handler=VNImageRequestHandler(ciImage: ciimage)
DispatchQueue.global(qos: .userInteractive).async{
    do{
        try handler.perform([request])
    }catch{
        print(error)
    }
}

【讨论】:

  • 这是在所有情况下对我都有帮助的唯一答案,包括当我的 UIImageView 嵌入到 UIScrollView 或方向更改时. StackOverflow 上的其他响应在某些情况下很有帮助,尤其是在处理像素缓冲区和实时摄像头馈送时,但这在几乎所有情况下对 UIImages 都非常有帮助。
  • 很高兴它可以帮助@ZbadhabitZ! :)
【解决方案2】:

这里没有足够的信息可以确定,但可能......

人脸识别需要知道图像方向。 (因为当您只寻找正面朝上的面孔时,准确地确定哪些像素块是面孔和不是面孔要容易得多。)

CGImage 不知道它自己的方向,因此您必须单独获取该信息并将其传递给VNImageRequestHandler 初始化器that takes an orientation 之一。

那些初始化程序采用 EXIF 方向值(又名CGImagePropertyOrientation)。如果您从UIImage 开始,则该枚举的基础数值与UIImageOrientation 的数值不匹配,因此您需要转换它们。在sample code attached to the Vision session from WWDC17 中有一个方便的方法。

【讨论】:

    【解决方案3】:

    这个问题也让我发疯了。原来的问题是 cgiImage 或 ciiImage 都无法正确处理的图像方向。我从某处复制的一些代码通过简单的转换错误地从图像转换为 cgi 方向(它们的顺序不同)。

    我创建了一个方向转换器,下面的代码适用于我:

    let handler = VNImageRequestHandler(cgImage: image.cgImage!, orientation: self.convertImageOrientation(orientation: image.imageOrientation))
    
    ...
    
    func convertImageOrientation(orientation: UIImageOrientation) -> CGImagePropertyOrientation  {
        let cgiOrientations : [ CGImagePropertyOrientation ] = [
            .up, .down, .left, .right, .upMirrored, .downMirrored, .leftMirrored, .rightMirrored
        ]
    
        return cgiOrientations[orientation.rawValue]
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-18
      • 2013-09-24
      • 1970-01-01
      • 2012-04-17
      • 1970-01-01
      • 2013-07-16
      • 2019-02-27
      • 2021-09-09
      • 2011-08-19
      相关资源
      最近更新 更多