iOS Vision框架人脸轮廓点转图像坐标错位问题求助
iOS人脸轮廓点坐标错位问题修复方案
问题核心是坐标系不匹配:Vision框架返回的归一化坐标基于图像原生坐标系(原点在左下角,y轴向上),而UIKit绘图用的是屏幕坐标系(原点在左上角,y轴向下),直接用VNImagePointForFaceLandmarkPoint得到的点会上下翻转,导致轮廓错位。
修复步骤
- 用
VNImagePointForFaceLandmarkPoint转换得到图像坐标系下的点 - 对转换后的y坐标进行垂直翻转,公式:
翻转后y = 图像高度 - 转换后y - (可选)替换
UIGraphicsBeginImageContext为UIGraphicsImageRenderer,避免Retina屏幕下图像模糊
修改后的完整代码
func faceRecognitionNormalisationPhase(faceObservation: VNFaceObservation, uiImage: UIImage) -> UIImage { let renderer = UIGraphicsImageRenderer(size: uiImage.size) let newImage = renderer.image { context in uiImage.draw(at: .zero) let cgContext = context.cgContext cgContext.setFillColor(UIColor.red.cgColor) cgContext.setStrokeColor(UIColor.red.cgColor) guard let faceContour = faceObservation.landmarks?.faceContour else { return } let imageSize = uiImage.size let boundingBox = faceObservation.boundingBox for i in 0..<faceContour.pointCount { let normalizedPoint = faceContour.normalizedPoints[i] // 转换为图像坐标系下的点(原点左下角) let imagePoint = VNImagePointForFaceLandmarkPoint( vector_float2(Float(normalizedPoint.x), Float(normalizedPoint.y)), boundingBox, Int(imageSize.width), Int(imageSize.height) ) // 转换为UIKit坐标系(原点左上角) let uiKitX = CGFloat(imagePoint.x) let uiKitY = imageSize.height - CGFloat(imagePoint.y) // 绘制标记点 let pointRect = CGRect(x: uiKitX - 5, y: uiKitY - 5, width: 10, height: 10) cgContext.fillEllipse(in: pointRect) } } UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil) return newImage }
额外说明
如果你的图片是前置摄像头拍摄的镜像图,还需要对x坐标进行翻转(翻转后x = 图像宽度 - 转换后x),否则左右轮廓会颠倒。
内容的提问来源于stack exchange,提问作者riser101
相关产品推荐
相关产品推荐

