2017-06-15 306 views
0

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

这是我的函数:

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) 
+0

这里到底问什么? – rambossa

+0

@rambossa为什么使用的函数返回空结果没有任何错误 –

回答

3

这里有不是很足够的信息来确定,但很可能...

人脸识别要求图像的方向是已知的。 (因为准确计算出哪些像素点是不是脸部,当你只是在寻找右侧面时,更容易一些。)

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

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

3

如果要检测脸部,并借鉴各一个矩形,试试这个:

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) 
    } 
} 
+1

这是唯一的答案,在所有情况下都对我有帮助,包括当我的* UIImageView *嵌入* UIScrollView *或方向更改时。在某些情况下,对StackOverflow的其他响应已经有所帮助,特别是在处理像素缓冲区和实时相机馈送时,但对于几乎所有情况下的UIImage都非常有用。 – ZbadhabitZ

+0

很高兴它可以帮助@ZbadhabitZ! :) –

0

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

我已经创建了一个方向转换器和下面的代码工作对我来说:

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] 
}