如何手动构建 AVDepthData

2023-12-10

我想构建自己的深度图并保存带有深度信息的图像,例如肖像照片。所以首先我需要生成 AVDepthData。在挖掘了它的构建方式之后,我尝试重现它:

func buildDepth() {
    // ...
    let info: [AnyHashable: Any] = [kCGImagePropertyPixelFormat: kCVPixelFormatType_DisparityFloat32,
                                    kCGImagePropertyWidth: width,
                                    kCGImagePropertyHeight: height,
                                    kCGImagePropertyBytesPerRow: bytesPerRow]
    let metadata = generateMetadata(photo: photo)
    let dic: [AnyHashable: Any] = [kCGImageAuxiliaryDataInfoDataDescription: info,
                                   kCGImageAuxiliaryDataInfoData: data,
                                   kCGImageAuxiliaryDataInfoMetadata: metadata]
    guard let depthData = try? AVDepthData(fromDictionaryRepresentation: dic) else {
        return false
    }
    print(depthData.cameraCalibrationData) // <----- prints nil
}

private static func generateMetadata(photo: Photo) -> CGImageMetadata {
    let metadata = CGImageMetadataCreateMutable()

    let fxy = max(photo.orig.size.width, photo.orig.size.height)
    let cx = photo.orig.size.width/2
    let cy = photo.orig.size.height/2

    addMetadataTag(metadata, key: "Filtered", value: true)
    addMetadataTag(metadata, key: "Quality", value: "high")
    addMetadataTag(metadata, key: "Accuracy", value: "relative")
    addMetadataTag(metadata, key: "DepthDataVersion", value: 65538)
    addMetadataTag(metadata, key: "PixelSize", value: 0.001000)


    addMetadataTag(metadata, key: "LensDistortionCoefficients", value: [0,0,0,0,0,0,0,0])
    addMetadataTag(metadata, key: "InverseLensDistortionCoefficients", value: [0,0,0,0,0,0,0,0])


    addMetadataTag(metadata, key: "IntrinsicMatrixReferenceWidth", value: photo.orig.size.width)
    addMetadataTag(metadata, key: "IntrinsicMatrixReferenceHeight", value: photo.orig.size.height)
    addMetadataTag(metadata, key: "LensDistortionCenterOffsetX", value: cx)
    addMetadataTag(metadata, key: "LensDistortionCenterOffsetY", value: cy)
    addMetadataTag(metadata, key: "ExtrinsicMatrix", value: [1,0,0,
                                                                  0,1,0,
                                                                  0,0,1,
                                                                  0,0,0])

    addMetadataTag(metadata, key: "IntrinsicMatrix", value: [fxy,0,0,
                                                                  0,fxy,0,
                                                                  cx,cy,1])

    addMetadataTag(metadata, type: .depthBlur, key: "SimulatedAperture", value: 4.5)
    addMetadataTag(metadata, type: .depthBlur, key: "RenderingParameters", value: "UkVORAEAAAAwAAAAAgAAAJqZmT4K1yM8F0iSOTVeuj0zM7M/DdXOOwAAAD+amRk+")
    print(metadata)
    return metadata
}

enum MetadataType {
    case depth, depthBlur
}

@discardableResult private static func addMetadataTag(_ metadata: CGMutableImageMetadata, type: MetadataType = .depth, key: String, value: Any) -> Bool {
    let namespace: String
    let prefix: String
    switch type {
    case .depth:
        namespace = "http://ns.apple.com/depthData/1.0/"
        prefix = "depthData"
    case .depthBlur:
        namespace = "http://ns.apple.com/depthBlurEffect/1.0/"
        prefix = "depthBlurEffect"
    }
    guard let metadataTag = CGImageMetadataTagCreate(namespace as CFString, prefix as CFString, key as CFString, .default, value as CFTypeRef)
        else { return false }

    print("type", CGImageMetadataTagGetType(metadataTag).rawValue)
    return CGImageMetadataSetTagWithPath(metadata, nil, ("xmp:"+key) as CFString, metadataTag)
}

之后我得到AVDepthData女巫我可以保存到图像中。但此数据不包含任何附加信息,例如cameraCalibrationData。系统生成的词典看起来和我的词典很相似。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何手动构建 AVDepthData 的相关文章

随机推荐