我正在使用以下代码提取深度图(按照苹果自己的示例):
- (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) {
}];
结果是:这是低质量的图片(已旋转,但现在暂时放开方向)图像:
然后,我已经转移了原始的HEIC文件,在Photoshop中打开该文件,转到了Channels,然后选择了如下的深度图:
这是结果:
这是分辨率/质量更高,方向正确的深度图。为什么代码(实际上是https://developer.apple.com/documentation/avfoundation/avdepthdata/2881221-depthdatafromdictionaryrepresent?language=objc上的Apple自己的代码)导致质量较低的结果?
答案 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
方法中解决了方向问题。照顾了方向。