Преобразование координат CIImage в CGRect из CIFaceFeature - PullRequest
0 голосов
/ 31 мая 2018

Я пытаюсь разместить квадратный прямоугольник над лицом пользователя, который я распознаю, используя CIFaceFeature в режиме реального времени по полноэкранному (self.view.frame) видеоподушку.Однако координаты, которые я получаю от CIFaceFeature.bounds, взяты из другой системы координат, чем та, которая используется представлениями.Я попытался преобразовать эти координаты из this и других примеров .Но так как я не запускаю это поверх видеопотока, у меня нет изображения, которое я могу передать в CIImage, чтобы облегчить преобразование координат.Ниже приведен пример моей конфигурации, любая идея, как я могу преобразовать в пригодный для использования CGRect?

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

    let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
    let opaqueBuffer = Unmanaged<CVImageBuffer>.passUnretained(imageBuffer!).toOpaque()
    let pixelBuffer = Unmanaged<CVPixelBuffer>.fromOpaque(opaqueBuffer).takeUnretainedValue()
    let sourceImage = CIImage(cvPixelBuffer: pixelBuffer)
    let features = self.faceDetector!.features(in: sourceImage, options: options)

    if (features.count != 0) {
        let faceImage = sourceImage
        let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
        let faces = faceDetector?.features(in: faceImage) as! [CIFaceFeature]

        let transformScale = CGAffineTransform(scaleX: 1, y: -1)
        let transform = transformScale.translatedBy(x: 0, y: -faceImage.extent.height)
        for feature in features as! [CIFaceFeature] {

            faceBounds = feature.bounds

            var fb = faceBounds?.applying(transform)
            // imageViewSize is the screen frame
            let scale = min(imageViewSize.width / fb!.width,
                            imageViewSize.height / fb!.height)

            let dx = (imageViewSize.width - fb!.width * scale) / 2
            let dy = (imageViewSize.height - fb!.height * scale) / 2

            fb?.applying(CGAffineTransform(scaleX: scale, y: scale))
            fb?.origin.x += dx
            fb?.origin.y += dy

            realFaceRect = fb // COMPLETELY WRONG :'(
    }
}

1 Ответ

0 голосов
/ 01 июня 2018

Если кто-то столкнется с той же проблемой.Вот простое решение

let imgHeight = CGFloat(CVPixelBufferGetHeight(pixelBuffer))
let ratio = self.view.frame.width / self.visage!.imgHeight

func convertFrame(frame: CGRect, ratio: CGFloat) -> CGRect {
    let x = frame.origin.y * ratio
    let y = frame.origin.x * ratio
    let width = frame.height * ratio
    let height = frame.width * ratio
    return CGRect(x: x, y: y, width: width, height: height)
}

func convertPoint(point: CGPoint, ratio: CGFloat) -> CGPoint {
    let x = point.y * ratio
    let y = point.x * ratio
    return CGPoint(x: x, y: y)
}
...