swift - 当 AVCaptureConnection videoOrientation 设置为纵向时,MLKit 人脸跟踪无法在视频流中找到人脸
问题描述
我正在尝试使用Metal / Scenekit
渲染器进行一些前置摄像头面部跟踪(是的,重新发明 snapchat)
我Firebase
用于面部跟踪
我有一个问题,设置AVCaptureConnection
videoOrientation 导致没有检测到面部
public func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
do {
var textures: [MTLTexture]!
delegate?.metalCameraSession(self, didSendRawSampleBufferForFaceDetection: sampleBuffer)
connection.videoOrientation = .portrait//portrait causes no faces to be detected
connection.isVideoMirrored = true
guard let imageBuffer = sampleBuffer.imageBuffer else {
throw MetalCameraSessionError.failedToGetImageBuffer
}
switch pixelFormat {
case .rgb:
let textureRGB = try texture(sampleBuffer: imageBuffer, textureCache: textureCache)
textures = [textureRGB]
case .yCbCr:
let textureY = try texture(sampleBuffer: imageBuffer, textureCache: textureCache, planeIndex: 0, pixelFormat: .r8Unorm)
let textureCbCr = try texture(sampleBuffer: imageBuffer, textureCache: textureCache, planeIndex: 1, pixelFormat: .rg8Unorm)
textures = [textureY, textureCbCr]
}
let timestamp = try self.timestamp(sampleBuffer: sampleBuffer)
delegate?.metalCameraSession(self, didReceiveFrameAsTextures: textures, withTimestamp: timestamp, andImageBuffer :sampleBuffer)
}
catch let error as MetalCameraSessionError {
self.handleError(error)
}
catch {
/**
* We only throw `MetalCameraSessionError` errors.
*/
}
}
如果我不将其设置为纵向,一切都很好,但我的 MTLTexture 会旋转和拉伸
纹理创建如下:
private func texture(sampleBuffer: CVImageBuffer?, textureCache: CVMetalTextureCache?, planeIndex: Int = 0, pixelFormat: MTLPixelFormat = .bgra8Unorm) throws -> MTLTexture {
guard let sampleBuffer = sampleBuffer else {
throw MetalCameraSessionError.missingSampleBuffer
}
guard let textureCache = textureCache else {
throw MetalCameraSessionError.failedToCreateTextureCache
}
let isPlanar = CVPixelBufferIsPlanar(sampleBuffer)
let width = isPlanar ? CVPixelBufferGetWidthOfPlane(sampleBuffer, planeIndex) : CVPixelBufferGetWidth(sampleBuffer)
let height = isPlanar ? CVPixelBufferGetHeightOfPlane(sampleBuffer, planeIndex) : CVPixelBufferGetHeight(sampleBuffer)
var imageTexture: CVMetalTexture?
let result = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, sampleBuffer, nil, pixelFormat, width, height, planeIndex, &imageTexture)
guard
let unwrappedImageTexture = imageTexture,
let texture = CVMetalTextureGetTexture(unwrappedImageTexture),
result == kCVReturnSuccess
else {
throw MetalCameraSessionError.failedToCreateTextureFromImage
}
return texture
}
即使我在更改 videoOrientation 和创建金属纹理之前将样本缓冲区发送到人脸检测器,情况仍然如此(没有人脸跟踪)
解决方案
推荐阅读
- asp.net-mvc - 从 ADFS 3.0 重定向回来后,asp.net MVC 应用程序上的会话集丢失
- c# - 每隔指定次数将字符串值拆分为数组的更简单方法是什么?
- ios - 尝试通过情节提要参考打开视图控制器时崩溃
- javascript - 从 json 输出图像到测试,作为问题的补充
- python - fastq 文件中的异常写入错误:标题移动到第 4 行,即质量得分值行
- reactjs - 笑话:如何在 onChange 方法中更新模拟函数的值?
- python - 将列添加到依赖于现有列及其 qcut bin 值的数据框
- node.js - 是否有可能在 typedi 中调用 Container.get() 内的构造函数?
- android - 如何使用 NanoHttp 将文件从 web 上传到 android web 服务器
- ios - iTunes Connect - 未发送测试飞行邀请以进行内部测试