【问题标题】:How to draw the `normalizedPoints` of `VNFaceLandmarkRegion2D` on my UIView?如何在我的 UIView 上绘制 `VNFaceLandmarkRegion2D` 的 `normalizedPoints`?
【发布时间】:2018-04-17 04:34:38
【问题描述】:

我正在尝试画一个圆圈来表示VNDetectFaceLandmarksRequest检测到的leftPupil的结果。

按照normalizedPoints 的命名约定,我猜它是由一些规则规范化的。那么,如何缩放并将该点转换为我的AVCaptureVideoPreviewLayer 或其他视图?

从一些 Vision 教程中,我看到了如下转换:

let faceLandmarkPoints = convertedPoints.map { (point: (x: CGFloat, y: CGFloat)) -> (x: CGFloat, y: CGFloat) in
                    let pointX = point.x * boundingBox.width + boundingBox.origin.x
                    let pointY = point.y * boundingBox.height + boundingBox.origin.y

                    return (x: pointX, y: pointY)
                }

但是,这对我来说真的不起作用。我的完整代码如下。

转换:

// Rescale the points from vision coordinates
func convertPointsForFace(landmark: VNFaceLandmarkRegion2D?, _ boundingBox: CGRect)
    -> [(x: CGFloat, y: CGFloat)]?{
        if let points = landmark?.normalizedPoints{
            let convertedPoints = self.convertToCGFloat(points: points)

            let faceLandmarkPoints = convertedPoints.map { (point: (x: CGFloat, y: CGFloat)) -> (x: CGFloat, y: CGFloat) in
                let pointX = point.x * boundingBox.width + boundingBox.origin.x
                let pointY = point.y * boundingBox.height + boundingBox.origin.y

                return (x: pointX, y: pointY)
            }
            return faceLandmarkPoints
        }
        return nil
}

画点:

// Draw a point on preview layer
func drawPoint(point: (x: CGFloat, y: CGFloat)){
    // We use a CAShaperLayer to draw the circle
    let shapeLayer = CAShapeLayer()
    let circlePath = UIBezierPath(arcCenter: CGPoint(x: point.x,y: point.y),
                                  radius: CGFloat(20),
                                  startAngle: CGFloat(0),
                                  endAngle:CGFloat(Double.pi * 2),
                                  clockwise: true)
    shapeLayer.path = circlePath.cgPath
    shapeLayer.fillColor = UIColor.red.cgColor
    shapeLayer.strokeColor = UIColor.red.cgColor
    shapeLayer.lineWidth = 1.0
    self.previewLayer.addSublayer(shapeLayer)
}

VNDetectFaceLandmarksRequest 完成处理程序:

func landmarkDetectCcompletionHandler(request: VNRequest, _ error: Error?){
    if error != nil {
        print("Errors in the landmark detection: \(error.debugDescription)")
    }
    guard let observations = request.results as? [VNFaceObservation] else {
        fatalError("Failed to convert result to VNFaceObservation type")
    }
    for face in observations {

        DispatchQueue.main.async {
            [weak self] in
            let faceBox = face.boundingBox
            let leftEye = face.landmarks?.leftPupil
            let leftEyePoints = self?.convertPointsForFace(landmark: leftEye,
                                                           faceBox)
            print(leftEyePoints?.first!.x, leftEyePoints?.first!.y)
            self?.drawPoint(point: (leftEyePoints?.first)!)
        }
    }
}

实心圆圈始终显示在我的AVCaptureVideoPreviewLayer 的左上角。

【问题讨论】:

    标签: ios iphone swift uiview


    【解决方案1】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多