VNFaceObservation BoundingBox не масштабируется в портретном режиме

Для справки: это вытекает из вопроса в 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 в книжной ориентации. .

** Неправильное размещение в портретной ориентации** Неправильное размещение в книжной ориентации

** Правильное размещение в альбомной ориентации** Правильное размещение в альбомной ориентации


person ZbadhabitZ    schedule 17.07.2017    source источник


Ответы (2)


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)

person Bluewings    schedule 26.07.2017
comment
Благодарю вас! Это отлично сработало для того, что я искал. Я просто не мог правильно рассчитать, но ваше руководство привело меня в нужное место. Спасибо! - person ZbadhabitZ; 29.07.2017

Я думаю, вы должны обеспечить правильную ориентацию 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))

Для фронтальной камеры мы должны использовать левую зеркальную ориентацию.

person Rajender Kumar    schedule 28.07.2017