AVDepthData中的深度图不同于Photoshop中的HEIC文件深度数据

时间:2018-12-13 01:06:56

标签: ios image-processing ios12 avdepthdata

我正在使用以下代码提取深度图(按照苹果自己的示例):

- (nullable AVDepthData *)depthDataFromImageData:(nonnull NSData *)imageData orientation:(CGImagePropertyOrientation)orientation {
    AVDepthData *depthData = nil;

    CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
    if (imageSource) {
        NSDictionary *auxDataDictionary = (__bridge NSDictionary *)CGImageSourceCopyAuxiliaryDataInfoAtIndex(imageSource, 0, kCGImageAuxiliaryDataTypeDisparity);
        if (auxDataDictionary) {
            depthData = [[AVDepthData depthDataFromDictionaryRepresentation:auxDataDictionary error:NULL] depthDataByApplyingExifOrientation:orientation];
        }

        CFRelease(imageSource);
    }

    return depthData;
}

我称呼它为:

[[PHAssetResourceManager defaultManager] requestDataForAssetResource:[PHAssetResource assetResourcesForAsset:asset].firstObject options:nil dataReceivedHandler:^(NSData * _Nonnull data) {
    AVDepthData *depthData = [self depthDataFromImageData:data orientation:[self CGImagePropertyOrientationForUIImageOrientation:pickedUiImageOrientation]];
    CIImage *image = [CIImage imageWithDepthData:depthData];
    UIImage *uiImage = [UIImage imageWithCIImage:image];
    UIGraphicsBeginImageContext(uiImage.size);
    [uiImage drawInRect:CGRectMake(0, 0, uiImage.size.width, uiImage.size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData *pngData = UIImagePNGRepresentation(newImage);
    UIImage* pngImage = [UIImage imageWithData:pngData];    // rewrap
    UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil);
} completionHandler:^(NSError * _Nullable error) {

}];

结果是:这是低质量的图片(已旋转,但现在暂时放开方向)图像:

enter image description here

然后,我已经转移了原始的HEIC文件,在Photoshop中打开该文件,转到了Channels,然后选择了如下的深度图:

enter image description here

这是结果:

enter image description here

这是分辨率/质量更高,方向正确的深度图。为什么代码(实际上是https://developer.apple.com/documentation/avfoundation/avdepthdata/2881221-depthdatafromdictionaryrepresent?language=objc上的Apple自己的代码)导致质量较低的结果?

1 个答案:

答案 0 :(得分:0)

我找到了问题。实际上,它躲藏在视线中。从+[AVDepthData depthDataFromDictionaryRepresentation:error:]方法获得的结果返回 disparity 数据。我已使用以下代码将其转换为 depth

if(depthData.depthDataType != kCVPixelFormatType_DepthFloat32){
    depthData = [depthData depthDataByConvertingToDepthDataType:kCVPixelFormatType_DepthFloat32];
}

(还没有尝试过,但是16位深度kCVPixelFormatType_DepthFloat16应该也可以正常工作)

将视差转换为深度后,图像与Photoshop中的图像完全相同。我应该在使用CGImageSourceCopyAuxiliaryDataInfoAtIndex(imageSource, 0, kCGImageAuxiliaryDataTypeDisparity);时醒来(请注意最后的“视差”),而Photoshop显然是在说“深度图”,将视差转换为深度(或者说以某种方式阅读为深度,老实说,不知道物理编码,也许当我首先复制aux数据时,iOS正在将深度转换为视差。

旁注:我还通过直接从[PHAsset requestContentEditingInputWithOptions:completionHandler:]方法创建图像源并将contentEditingInput.fullSizeImageURL传递到CGImageSourceCreateWithURL方法中解决了方向问题。照顾了方向。