Skip to content

Instantly share code, notes, and snippets.

@giomurru
Created July 5, 2021 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giomurru/c36a616cf0d7075d49282c749c25e27b to your computer and use it in GitHub Desktop.
Save giomurru/c36a616cf0d7075d49282c749c25e27b to your computer and use it in GitHub Desktop.
VNFaceObservation: Computes the landmarks normalized on the smallest bounding box which includes all of the landmarks.
extension VNFaceObservation {
func landmarksBBox(_ imageSize: CGSize) -> (bbox: CGRect, landmarks: [CGPoint]) {
guard let allPoints = self.landmarks?.allPoints?.pointsInImage(imageSize: imageSize),
allPoints.count > 0 else { return (CGRect.zero, []) }
var maxX : CGFloat = -CGFloat.greatestFiniteMagnitude
var minX : CGFloat = CGFloat.greatestFiniteMagnitude
var maxY = maxX
var minY = minX
allPoints.forEach { point in
if point.x > maxX {
maxX = point.x
}
if point.y > maxY {
maxY = point.y
}
if point.x < minX {
minX = point.x
}
if point.y < minY {
minY = point.y
}
}
let bboxWidth = (maxX - minX)
let bboxHeight = (maxY - minY)
let normalizedBBoxOrigin = CGPoint(x: minX/imageSize.width, y: minY/imageSize.height)
let normalizedBBoxSize = CGSize(width: bboxWidth / imageSize.width, height: bboxHeight / imageSize.height)
let normalizedBBox = CGRect(origin: normalizedBBoxOrigin, size: normalizedBBoxSize)
//compute the normalized points with respect to the new bounding box
let normalizedPoints = allPoints.map { point -> CGPoint in
let normalizedPoint = CGPoint(x: point.x/imageSize.width, y: point.y/imageSize.height)
let normalizationFactor = CGSize(width: imageSize.width / bboxWidth, height: imageSize.height / bboxHeight)
return CGPoint(x: (normalizedPoint.x - normalizedBBoxOrigin.x) * normalizationFactor.width, y: (normalizedPoint.y - normalizedBBoxOrigin.y) * normalizationFactor.height)
}
return (normalizedBBox, normalizedPoints)
}
}
@giomurru
Copy link
Author

giomurru commented Jul 5, 2021

The usual VNFaceObservation bounding box does not always contain all the landmarks. This extension computes the smallest bounding box containing all the landmarks. The bounding box is expressed as normalized in the image dimension, while the landmarks are expressed as normalized in the bounding box dimension.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment