ios - 如何从相机图像中获取深度数据

标签 ios swift avcapturephotooutput avdepthdata

我正在编写一个应用程序来从相机拍摄的照片中获取深度数据和视差数据。我可以获得视差数据,但不能获取深度数据,它总是返回零。我需要获取深度信息 并将其另存为jpg

我尝试了下面的代码,用户可以在前置摄像头和后置摄像头之间切换并拍照,然后我们拍摄的照片将是过程

import UIKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var ImageView: UIView!

    var img:UIImage?
    var rgbImage:UIImage?

    var captureSession: AVCaptureSession?
    var videoPreviewLayer: AVCaptureVideoPreviewLayer?
    var backCamera = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
    var frontCamera = AVCaptureDevice.default(.builtInTrueDepthCamera, for: .video, position: .front)
    var capturePhotoOut : AVCapturePhotoOutput?

    override func viewDidLoad() {
        super.viewDidLoad()

        if #available(iOS 10.2, *){
            let captureDevice = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
            do{
                let input = try  AVCaptureDeviceInput(device: captureDevice!)
                captureSession = AVCaptureSession()
                captureSession?.addInput(input)
                videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
                videoPreviewLayer?.frame = view.layer.bounds
                ImageView.layer.addSublayer(videoPreviewLayer!)
                captureSession?.startRunning()
            }catch{
                print("error")
            }
        }

        capturePhotoOut = AVCapturePhotoOutput()
        capturePhotoOut?.isHighResolutionCaptureEnabled = true
        captureSession?.sessionPreset = .photo
        captureSession?.addOutput(capturePhotoOut!)
        capturePhotoOut!.isDepthDataDeliveryEnabled = capturePhotoOut!.isDepthDataDeliverySupported
        capturePhotoOut!.isPortraitEffectsMatteDeliveryEnabled = capturePhotoOut!.isPortraitEffectsMatteDeliverySupported
    }


    @IBAction func imageCapture(_ sender: Any) {
        guard let capturePhotoOutput = self.capturePhotoOut else {return}
        let photoSettings = AVCapturePhotoSettings()
        photoSettings.isAutoStillImageStabilizationEnabled = true
        photoSettings.isHighResolutionPhotoEnabled = true
        photoSettings.isDepthDataDeliveryEnabled = true
        photoSettings.isPortraitEffectsMatteDeliveryEnabled = true
        capturePhotoOut?.capturePhoto(with: photoSettings, delegate: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let vc = segue.destination   as! DepthImageView
        vc.img = img
        vc.rgbImg = rgbImage
    }


extension ViewController : AVCapturePhotoCaptureDelegate{
    public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
        guard error == nil else{return}
        guard let imageData = photo.fileDataRepresentation() else {return}


        let detailImage = UIImage.init(data: imageData,scale: 1.0)
        rgbImage = detailImage

        let nsData = imageData as NSData
        let ptr = nsData.bytes.assumingMemoryBound(to: UInt8.self)

        let cfDataset = CFDataCreate(nil,ptr,imageData.count)


        guard let source = CGImageSourceCreateWithData(cfDataset!,nil) else {return}

        guard let auxDataInfo = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeDepth) as? [String : AnyObject] else {
            return
        }

        var depthData: AVDepthData

        do {
            depthData = try AVDepthData(fromDictionaryRepresentation: auxDataInfo)

            if depthData.depthDataType != kCVPixelFormatType_DepthFloat32 {
                depthData = depthData.converting(toDepthDataType: kCVPixelFormatType_DepthFloat32)
            }

            let depthDataMap = depthData.depthDataMap

            let ciImage = CIImage(cvPixelBuffer: depthDataMap)

            let depthDataMapImage = UIImage(ciImage: ciImage,scale: 1.0,orientation: .down)
            img = depthDataMapImage
            self.performSegue(withIdentifier: "ImageViewScreen", sender: self)

        } catch {
            print("Error")
        }
    }
}

我在 auxDataInfo 守卫处总是得到 nil

最佳答案

AVCapturePhoto 包含有关 AVDepthData 的信息。尝试从照片中获取深度数据

let depthData = photo.depthData

关于ios - 如何从相机图像中获取深度数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57143477/

相关文章:

ios - 如何将图像数组转换为字符串

ios - 如何在 Swift 2.2 中使用 ResearchKit 在自定义事件步骤中禁用下一步按钮?

swift - DDXMLElement 的奇怪问题

ios - 拍照后如何暂停?

ios - AVCapturePhotoOutput 崩溃

ios - 识别虚假的应用内 iOS

javascript - 从 itunes connect 获取所有订阅组和产品 ID

ios - iPhone 6 中调用网络服务错误

objective-c - 使用类似于Apple的avTouch项目的AVAudioPlayer