VNDetectFaceRectanglesRequest检测脸部
我正在使用Vision框架来处理图像。我正在使用的函数运行良好,不会在完成处理程序中返回任何错误,但结果为空。VNDetectFaceRectanglesRequest检测脸部
这是我的函数:
func recognizeImage() {
let request = VNDetectFaceRectanglesRequest { (res: VNRequest, error: Error?) in
print("Reuslt : \(res.accessibilityActivationPoint)")
}
if let cgContet = image.image.cgImage {
let handler = VNImageRequestHandler(cgImage: cgContet)
try? handler.perform([request])
}
}
结果的功能是:
Reuslt : (0.0, 0.0)
这里有不是很足够的信息来确定,但很可能...
人脸识别要求图像的方向是已知的。 (因为准确计算出哪些像素点是不是脸部,当你只是在寻找右侧面时,更容易一些。)
CGImage
不知道它是自己的方向,因此您必须单独获取该信息并将其传递给VNImageRequestHandler
初始化程序that takes an orientation之一。
那些初始值设定项采用EXIF方向值(又名CGImagePropertyOrientation
)。如果您从UIImage
开始,则该枚举的基础数值与UIImageOrientation
不匹配,因此您需要将其转换。在sample code attached to the Vision session from WWDC17中有一个方便的方法。
如果要检测脸部,并借鉴各一个矩形,试试这个:
let request=VNDetectFaceRectanglesRequest{request, error in
var final_image=UIImage(named: image_to_process)
if let results=request.results as? [VNFaceObservation]{
print(results.count, "faces found")
for face_obs in results{
//draw original image
UIGraphicsBeginImageContextWithOptions(final_image.size, false, 1.0)
final_image.draw(in: CGRect(x: 0, y: 0, width: final_image.size.width, height: final_image.size.height))
//get face rect
var rect=face_obs.boundingBox
let tf=CGAffineTransform.init(scaleX: 1, y: -1).translatedBy(x: 0, y: -final_image.size.height)
let ts=CGAffineTransform.identity.scaledBy(x: final_image.size.width, y: final_image.size.height)
let converted_rect=rect.applying(ts).applying(tf)
//draw face rect on image
let c=UIGraphicsGetCurrentContext()!
c.setStrokeColor(UIColor.red.cgColor)
c.setLineWidth(0.01*final_image.size.width)
c.stroke(converted_rect)
//get result image
let result=UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
final_image=result!
}
}
//display final image
DispatchQueue.main.async{
self.image_view.image=final_image
}
}
guard let ciimage=CIImage(image:image_to_process) else{
fatalError("couldn't convert uiimage to ciimage")
}
let handler=VNImageRequestHandler(ciImage: ciimage)
DispatchQueue.global(qos: .userInteractive).async{
do{
try handler.perform([request])
}catch{
print(error)
}
}
这是唯一的答案,在所有情况下都对我有帮助,包括当我的* UIImageView *嵌入* UIScrollView *或方向更改时。在某些情况下,对StackOverflow的其他响应已经有所帮助,特别是在处理像素缓冲区和实时相机馈送时,但对于几乎所有情况下的UIImage都非常有用。 – ZbadhabitZ
很高兴它可以帮助@ZbadhabitZ! :) –
这个问题让我发疯了。原来的问题是cgiImage或ciiImage无法正确处理图像的方向。我从某处复制的一些代码通过简单的转换(它们不是相同的顺序)从图像转换为错误的方向。
我已经创建了一个方向转换器和下面的代码工作对我来说:
let handler = VNImageRequestHandler(cgImage: image.cgImage!, orientation: self.convertImageOrientation(orientation: image.imageOrientation))
...
func convertImageOrientation(orientation: UIImageOrientation) -> CGImagePropertyOrientation {
let cgiOrientations : [ CGImagePropertyOrientation ] = [
.up, .down, .left, .right, .upMirrored, .downMirrored, .leftMirrored, .rightMirrored
]
return cgiOrientations[orientation.rawValue]
}
这里到底问什么? – rambossa
@rambossa为什么使用的函数返回空结果没有任何错误 –