4

I want to Draw the Vector image of the Face by detecting the Face points using Vision I have created a code in which I am getting a few points and I have downloaded the code to Draw lines but I am unable to understand it and Customise the Lines. Please help me to understand the Code and if anyone can help me how I can Draw points on the face using the Face Detection code that I have, my code to detect face is :

          func drawOnImage(source: UIImage,
                             boundingRect: CGRect,
                             faceLandmarkRegions: [VNFaceLandmarkRegion2D]) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(source.size, false, 1)
    let context = UIGraphicsGetCurrentContext()!
    context.translateBy(x: 0, y: source.size.height)
    context.scaleBy(x: 1.0, y: -1.0)
    context.setBlendMode(CGBlendMode.colorBurn)
    context.setLineJoin(.round)
    context.setLineCap(.round)
    context.setShouldAntialias(true)
    context.setAllowsAntialiasing(true)
    
    let rectWidth = source.size.width * boundingRect.size.width
    let rectHeight = source.size.height * boundingRect.size.height
    
    //draw image
    let rect = CGRect(x: 0, y:0, width: source.size.width, height: source.size.height)
    context.draw(source.cgImage!, in: rect)
    
    
    //draw bound rect
    var fillColor = UIColor.green
    fillColor.setFill()
    context.addRect(CGRect(x: boundingRect.origin.x * source.size.width,                  y:boundingRect.origin.y * source.size.height, width: rectWidth, height: rectHeight))
    context.drawPath(using: CGPathDrawingMode.stroke)
    
    //draw overlay
    fillColor = UIColor.red
    fillColor.setStroke()
    context.setLineWidth(2.0)
    for faceLandmarkRegion in faceLandmarkRegions {
        var points: [CGPoint] = []
        for i in 0..<faceLandmarkRegion.pointCount {
            let point = faceLandmarkRegion.normalizedPoints[i]
            let p = CGPoint(x: CGFloat(point.x), y: CGFloat(point.y))
            points.append(p)
        }
        let mappedPoints = points.map { CGPoint(x: boundingRect.origin.x * source.size.width + $0.x * rectWidth, y: boundingRect.origin.y * source.size.height + $0.y * rectHeight) }
        context.addLines(between: mappedPoints)
        context.drawPath(using: CGPathDrawingMode.stroke)
    }
    
    let coloredImg : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return coloredImg
}

i want to draw the vector image , with dot and lines on the Face

DonMag
  • 69,424
  • 5
  • 50
  • 86
Rajni Bajaj
  • 174
  • 9
  • *"I have created a code ... but I am unable to understand it ..."* -- Did you **create** that code, but you don't understand the code you wrote? Or, is this code you copied from somewhere, without learning about the Vision framework? – DonMag Jul 04 '23 at 13:43
  • I have copied the code, and now I am able to create the point and lines on the face but I am not getting the points of the forehead. can you help me to find the forehead points? – Rajni Bajaj Jul 04 '23 at 17:19

1 Answers1

1

Guys i have acheived My desired output using ARKit which provide the feature of Face Mask. i can now Add the face Mask on the face Detected i am sharing the code here .

import ARKit

Declare a property in the class

let sceneView = ARSCNView()

put the below code in ViewDidLoad() Method of the class

let frame = CGRect(x:0, y: 0, width: self.view.frame.size.width, 
height: self.cameraView.bounds.height)
    sceneView.frame = frame
    self.view.addSubview(sceneView)
 sceneView.delegate = self
    guard ARFaceTrackingConfiguration.isSupported else { return }
    let configuration = ARFaceTrackingConfiguration()
    configuration.isLightEstimationEnabled = true
    sceneView.session.run(configuration, options: [.resetTracking, 
    .removeExistingAnchors])

Add the Following two Delegate Methods in your class and inherit your class from ARSCNViewDelegate

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> 
SCNNode? {
    
    guard let device = sceneView.device else {
        return nil
    }
    
    let faceGeometry = ARSCNFaceGeometry(device: device)
    let node = SCNNode(geometry: faceGeometry)
    node.geometry?.firstMaterial?.fillMode = .lines
    
    return node
}

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for 
anchor: ARAnchor) {
    
    guard let faceAnchor = anchor as? ARFaceAnchor,
        let faceGeometry = node.geometry as? ARSCNFaceGeometry else {
            return
    }
    faceGeometry.update(from: faceAnchor.geometry) 
 }

now when you run your Code you will be able to see the face Detected has a face Mask of vector line on it

Rajni Bajaj
  • 174
  • 9