【问题标题】:VNFaceObservation BoundingBox Not Scaling In Portrait ModeVNFaceObservation BoundingBox 在纵向模式下不缩放
【发布时间】:2017-12-22 09:40:20
【问题描述】:

作为参考,这源于 Vision API 中的一个问题。我正在努力使用 Vision 通过VNDetectFaceRectanglesRequest 检测图像中的人脸,这在确定图像中正确的人脸数量并为每个人脸提供boundingBox 方面是成功的.

我的麻烦是,由于我的UIImageView(其中包含有问题的UIImage)正在使用.scaleAspectFit 内容模式,我在纵向模式下正确绘制边界框时遇到了巨大的困难(事情很好横向)。

这是我的代码;

func detectFaces(image: UIImage) {

    let detectFaceRequest = VNDetectFaceRectanglesRequest { (request, error) in
        if let results = request.results as? [VNFaceObservation] {
            for faceObservation in results {
                let boundingRect = faceObservation.boundingBox

                let transform = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -self.mainImageView.frame.size.height)
                let translate = CGAffineTransform.identity.scaledBy(x: self.mainImageView.frame.size.width, y: self.mainImageView.frame.size.height)
                let facebounds = boundingRect.applying(translate).applying(transform)

                let mask = CAShapeLayer()
                var maskLayer = [CAShapeLayer]()
                mask.frame = facebounds

                mask.backgroundColor = UIColor.yellow.cgColor
                mask.cornerRadius = 10
                mask.opacity = 0.3
                mask.borderColor = UIColor.yellow.cgColor
                mask.borderWidth = 2.0

                maskLayer.append(mask)
                self.mainImageView.layer.insertSublayer(mask, at: 1)
            }
         }

    let vnImage = VNImageRequestHandler(cgImage: image.cgImage!, options: [:])
    try? vnImage.perform([detectFaceRequest])

}


这是我所看到的最终结果,请注意,方框在其 X 位置是正确的,但在纵向时,它们的 Y 位置在很大程度上是不准确的。 p>

** 纵向放置不正确**

** 横向放置正确**

【问题讨论】:

    标签: ios swift core-graphics apple-vision


    【解决方案1】:

    VNFaceObservation 边界框被归一化为处理后的图像。来自文档。

    检测到的物体的边界框。坐标归一化为 处理后图像的尺寸,原点位于图像的 左下角。

    因此,您可以使用简单的计算来为检测到的人脸找到正确的尺寸/框架,如下所示。

    let boundingBox = observation.boundingBox
    let size = CGSize(width: boundingBox.width * imageView.bounds.width,
                      height: boundingBox.height * imageView.bounds.height)
    let origin = CGPoint(x: boundingBox.minX * imageView.bounds.width,
                         y: (1 - observation.boundingBox.minY) * imageView.bounds.height - size.height)
    

    然后你可以像下面这样形成CAShapeLayer rect

    layer.frame = CGRect(origin: origin, size: size)

    【讨论】:

    • 谢谢!这对我所追求的非常有用。我只是无法正确计算数学,但是您的指导使我处于正确的位置。谢谢!
    【解决方案2】:

    我认为您必须为 CIImage 提供正确的方向,同时发送以处理和检测面部。正如@Pawel Chmiel 在他的blog post 中提到的那样:

    这里重要的是我们需要提供正确的方向,因为此时人脸检测非常敏感,旋转的图像可能没有结果。

     let ciImage = CIImage(cvImageBuffer: pixelBuffer!, options: attachments as! [String : Any]?)
    
     //leftMirrored for front camera
     let ciImageWithOrientation = ciImage.applyingOrientation(Int32(UIImageOrientation.leftMirrored.rawValue))
    

    对于前置摄像头,我们必须使用leftMirrored方向

    【讨论】:

      猜你喜欢
      • 2018-05-01
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-03
      相关资源
      最近更新 更多