gpt4 book ai didi

ios - iOS 12 上的过滤深度数据似乎已旋转

转载 作者:行者123 更新时间:2023-12-03 09:25:44 27 4
gpt4 key购买 nike

我有一个问题,其中 .builtInDualCamera 的深度数据当 isFilteringEnabled = true 时似乎旋转了 90 度

这是我的代码:

fileprivate let session = AVCaptureSession()

fileprivate let meta = AVCaptureMetadataOutput()
fileprivate let video = AVCaptureVideoDataOutput()
fileprivate let depth = AVCaptureDepthDataOutput()

fileprivate let camera: AVCaptureDevice
fileprivate let input: AVCaptureDeviceInput

fileprivate let synchronizer: AVCaptureDataOutputSynchronizer

init(delegate: CaptureSessionDelegate?) throws {
self.delegate = delegate
session.sessionPreset = .vga640x480

// Setup Camera Input
let discovery = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera], mediaType: .video, position: .unspecified)
if let device = discovery.devices.first {
camera = device
} else {
throw SessionError.CameraNotAvailable("Unable to load camera")
}

input = try AVCaptureDeviceInput(device: camera)
session.addInput(input)

// Setup Metadata Output (Face)
session.addOutput(meta)
if meta.availableMetadataObjectTypes.contains(AVMetadataObject.ObjectType.face) {
meta.metadataObjectTypes = [ AVMetadataObject.ObjectType.face ]
} else {
print("Can't Setup Metadata: \(meta.availableMetadataObjectTypes)")
}

// Setup Video Output
video.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA]
session.addOutput(video)
video.connection(with: .video)?.videoOrientation = .portrait

// ****** THE ISSUE IS WITH THIS BLOCK HERE ******
// Setup Depth Output
depth.isFilteringEnabled = true
session.addOutput(depth)
depth.connection(with: .depthData)?.videoOrientation = .portrait

// Setup Synchronizer
synchronizer = AVCaptureDataOutputSynchronizer(dataOutputs: [depth, video, meta])


let outputRect = CGRect(x: 0, y: 0, width: 1, height: 1)
let videoRect = video.outputRectConverted(fromMetadataOutputRect: outputRect)
let depthRect = depth.outputRectConverted(fromMetadataOutputRect: outputRect)

// Ratio of the Depth to Video
scale = max(videoRect.width, videoRect.height) / max(depthRect.width, depthRect.height)

// Set Camera to the framerate of the Depth Data Collection
try camera.lockForConfiguration()
if let fps = camera.activeDepthDataFormat?.videoSupportedFrameRateRanges.first?.minFrameDuration {
camera.activeVideoMinFrameDuration = fps
}
camera.unlockForConfiguration()

super.init()
synchronizer.setDelegate(self, queue: syncQueue)
}

func dataOutputSynchronizer(_ synchronizer: AVCaptureDataOutputSynchronizer, didOutput data: AVCaptureSynchronizedDataCollection) {
guard let delegate = self.delegate else {
return
}

// Check to see if all the data is actually here
guard
let videoSync = data.synchronizedData(for: video) as? AVCaptureSynchronizedSampleBufferData,
!videoSync.sampleBufferWasDropped,
let depthSync = data.synchronizedData(for: depth) as? AVCaptureSynchronizedDepthData,
!depthSync.depthDataWasDropped
else {
return
}

// It's OK if the face isn't found.
let face: AVMetadataFaceObject?
if let metaSync = data.synchronizedData(for: meta) as? AVCaptureSynchronizedMetadataObjectData {
face = (metaSync.metadataObjects.first { $0 is AVMetadataFaceObject }) as? AVMetadataFaceObject
} else {
face = nil
}

// Convert Buffers to CIImage
let videoImage = convertVideoImage(fromBuffer: videoSync.sampleBuffer)
let depthImage = convertDepthImage(fromData: depthSync.depthData, andFace: face)

// Call Delegate
delegate.captureImages(video: videoImage, depth: depthImage, face: face)
}

fileprivate func convertVideoImage(fromBuffer sampleBuffer: CMSampleBuffer) -> CIImage {
// Convert from "CoreMovie?" to CIImage - fairly straight-forward
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let image = CIImage(cvPixelBuffer: pixelBuffer!)
return image
}

fileprivate func convertDepthImage(fromData depthData: AVDepthData, andFace face: AVMetadataFaceObject?) -> CIImage {

var convertedDepth: AVDepthData

// Convert 16-bif floats up to 32
if depthData.depthDataType != kCVPixelFormatType_DisparityFloat32 {
convertedDepth = depthData.converting(toDepthDataType: kCVPixelFormatType_DisparityFloat32)
} else {
convertedDepth = depthData
}

// Pixel buffer comes straight from depthData
let pixelBuffer = convertedDepth.depthDataMap

let image = CIImage(cvPixelBuffer: pixelBuffer)
return image
}

原始视频是这样的:(供引用)

Original Video Image

当值为:
// Setup Depth Output
depth.isFilteringEnabled = false
depth.connection(with: .depthData)?.videoOrientation = .portrait

图像看起来像这样:(你可以看到更近的夹克是白色的,更远的夹克是灰色的,远处是深灰色的——正如预期的那样)

Filtering=False, Orientation=Portrait

当值为:
// Setup Depth Output
depth.isFilteringEnabled = true
depth.connection(with: .depthData)?.videoOrientation = .portrait

图像如下所示:(您可以看到颜色值似乎在正确的位置,但平滑过滤器中的形状似乎被旋转了)

Filtering=True, Orientation=Portrait

当值为:
// Setup Depth Output
depth.isFilteringEnabled = true
depth.connection(with: .depthData)?.videoOrientation = .landscapeRight

图像看起来像这样:(颜色和形状看起来都是水平的)

Filtering=True, Orientation=Landscape_Right

我做错了什么来获得这些不正确的值吗?

我试过重新排序代码
// Setup Depth Output
depth.connection(with: .depthData)?.videoOrientation = .portrait
depth.isFilteringEnabled = true

但这没有任何作用。

我认为这是一个与 iOS 12 相关的问题,因为我记得这在 iOS 11 下工作得很好(虽然我没有保存任何图像来证明这一点)

任何帮助表示赞赏,谢谢!

最佳答案

与在 AVDepthData 中查看有关创建后旋转图像的其他答案的建议不同,我发现该建议不起作用。 documentation ,有一种方法可以为您进行方向校正。
方法调用:depthDataByApplyingExifOrientation:返回 AVDepthData 的实例应用方向,即。您可以通过传入您选择的参数,以您想要的正确方向创建您的图像。
这是我的辅助方法,它返回 UIImage与方向修复。

- (UIImage *)createDepthMapImageFromCapturePhoto:(AVCapturePhoto *)photo {
// AVCapturePhoto which has depthData - in swift you should confirm this exists
AVDepthData *frontDepthData = [photo depthData];
// Overwrite the instance with the correct orientation applied.
frontDepthData = [frontDepthData depthDataByApplyingExifOrientation:kCGImagePropertyOrientationRight];
// Create the CIImage from the depth data using the available method.
CIImage *ciDepthImage = [CIImage imageWithDepthData:frontDepthData];
// Create CIContext which enables converting CIImage to CGImage
CIContext *context = [[CIContext alloc] init];
// Create the CGImage
CGImageRef img = [context createCGImage:ciDepthImage fromRect:[ciDepthImage extent]];
// Create the final image.
UIImage *depthImage = [UIImage imageWithCGImage:img];
// Return the depth image.
return depthImage;
}

关于ios - iOS 12 上的过滤深度数据似乎已旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55009162/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com