0

作为参考,这源于Vision API中的一个问题。我正在努力使用Vision通过 a 检测图像中的人脸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位置在很大程度上是不准确的。

**纵向放置不正确** 纵向放置不正确

** 在风景中正确放置** 景观中的正确放置

4

2 回答 2

4

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如下的矩形

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

于 2017-07-26T05:12:33.997 回答
0

我认为您必须为 CIImage 提供正确的方向,同时发送以处理和检测人脸。正如@Pawel Chmiel 在他的博客文章中提到的那样:

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

 let ciImage = CIImage(cvImageBuffer: pixelBuffer!, options: attachments as! [String : Any]?)

 //leftMirrored for front camera
 let ciImageWithOrientation = ciImage.applyingOrientation(Int32(UIImageOrientation.leftMirrored.rawValue))

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

于 2017-07-28T11:42:41.153 回答