【问题标题】:Get Disparity or Depth Data from PHImageManager从 PHImageManager 获取视差或深度数据
【发布时间】:2020-01-14 23:39:48
【问题描述】:

我尝试从 PHAsset 获取视差图或深度图。我找到了从加载 PHImageMager 的图像中获取地图并实现它的示例:

- (AVDepthData*)getDepthDataFromSource:(CGImageSourceRef)source 
{
    NSDictionary* depthData = CFBridgingRelease(CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeDepth));
    if (!depthData){
        depthData = CFBridgingRelease(CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeDisparity));
    }
    if (!depthDat)
        return nil; //code returns here 

    NSError* creationError = nil;
    AVDepthData* data = [AVDepthData depthDataFromDictionaryRepresentation:depthData
                                                                    error:&creationError];
    return data;
}

//from a image
[[PHImageManager defaultManager]  requestImageForAsset:asset
                            targetSize:size
                            contentMode:contentMode
                            options:requestOptions
                            resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                            CGImageRef im = image.CGImage;
                            CGImageSourceRef source = CGImageSourceCreateWithDataProvider(CGImageGetDataProvider(im), (CFDictionaryRef)@{});
                            AVDepthData* data = [self getDepthDataFromSource:source];//data is nil
                            if (source != nil)
                            {
                                CFRelease(source);
                            }
                    }];

//from a data
    PHImageRequestOptions* imageDataRequestOptions = [[PHImageRequestOptions alloc] init];
    imageDataRequestOptions.networkAccessAllowed = YES;
    imageDataRequestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    PHImageRequestID requestId = [[PHImageManager defaultManager] requestImageDataForAsset:asset
                                                                                options:imageDataRequestOptions
                                                                            resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                                                                                CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imageData, (CFDictionaryRef)@{});
                                                                                AVDepthData* data = [self getDepthDataFromSource:source];//data is nil
                                                                                if (source != nil)
                                                                                {
                                                                                    CFRelease(source);
                                                                                }
                                                                            }
                                    ];

//from full resolution image
__block FADisparityDataReader* selfStong = self;
PHContentEditingInputRequestOptions* options = [[PHContentEditingInputRequestOptions alloc] init];
options.networkAccessAllowed = YES;
[asset requestContentEditingInputWithOptions:options
                                                        completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
    NSURL* fullSizePath = [contentEditingInput fullSizeImageURL];
    CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)fullSizePath, (CFDictionaryRef)@{});
    @onExit{
        CFRelease(source);
    };
    AVDepthData* data = [self readDepthDataFromSource:source]; //data is not nil
    complition(data);
}]; 

我只在requestContentEditingInputWithOptions 块中获取深度数据,但它太长了,我相信我可以从 PHImageManager 图像中获取深度图。 如何从 PHImageManager 获取数据?

【问题讨论】:

  • 偶然发现这个...不是因为您在 if (!depthDat) { 行中检查 depthDat 而不是 depthData?

标签: ios objective-c image


【解决方案1】:

2017 WWDC 会议'Editing with Depth' 有一些指导,但没有完整的代码示例。 您可以使用 Apple 示例应用程序“PhotoBrowse”来测试访问深度数据的方法。

查看我修改后的加载深度和视差图像的 PhotoBrowse。它使用 Accelerate 框架 vDSP 矢量函数将视差标准化为 0..1 范围 https://github.com/racewalkWill/PhotoBrowseModified

    @IBAction func showDepthBtn(_ sender: UIBarButtonItem) {
        // show the depth data from portrait mode from
        // iPhone 7 Plus and later camera
       requestDepthMap(selectedAsset: asset)
    }

    func requestDepthMap(selectedAsset: PHAsset)  {
       // may not have depthData in many cases
       // PH completionHandler may be invoked multiple times
       var auxImage: CIImage?
       let options = PHContentEditingInputRequestOptions()

       selectedAsset.requestContentEditingInput(with: options, completionHandler: { input, info in
           guard let input = input
               else { NSLog ("contentEditingInput not loaded")
                    return
               }
            auxImage = CIImage(contentsOf: input.fullSizeImageURL!, options: [CIImageOption.auxiliaryDepth: true])

            if auxImage != nil {
                let uiImage = UIImage(ciImage: auxImage! )
                self.imageView.image = uiImage
            }

       } )
   }

关键点是PHAsset requestContentEditingInput完成处理程序用于获取辅助深度(或视差)ciImage。

会话演示讨论了缩放和规范化,但没有发布任何示例代码或应用程序。请参阅我修改后的 PhotoBrowse 应用程序以规范化 CVPixelBuffer 深度数据。

还要确保使用 iPhone 人像模式拍摄有深度的照片。我个人照片库中的几乎所有图片都没有深度数据。

你的问题已经有一段时间了,所以你可能已经解决了这个问题。

【讨论】:

  • 从 iOS 14.4.2 开始,上面的 PhotoBrowse 示例深度代码不再读取 auxImage 的深度......某处发生了一些变化!我打算很快再讨论这个问题
猜你喜欢
  • 2020-06-15
  • 2014-05-27
  • 2018-04-05
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 2020-08-17
相关资源
最近更新 更多