不是答案,但是...
自从我开始使用代码制作具有深度功能的 Flutter 插件以来已经过去了三周,这是对带我去工作 PoC 的痛苦试验和错误的快速回顾:
(我为代码质量道歉,这也是我第一次使用objective-c)
- iOS 有大量的相机(硬件组合),只有一个子集支持深度数据。当您发现自己的设备时:
AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession
discoverySessionWithDeviceTypes:deviceTypes
mediaType:AVMediaTypeVideo
position:AVCaptureDevicePositionUnspecified];
您可以询问他们的深度能力:
for (AVCaptureDevice *device in devices) {
BOOL depthDataCapable;
if (@available(iOS 11.0, *)) {
AVCaptureDeviceFormat *activeDepthDataFormat = [device activeDepthDataFormat];
depthDataCapable = (activeDepthDataFormat != nil);
NSLog(@" -- %@ supports DepthData: %s", [device localizedName],
} else {
depthDataCapable = false;
}
}
在 iPhone12 上:
-- Front TrueDepth Camera supports DepthData: true
-- Back Dual Wide Camera supports DepthData: true
-- Back Ultra Wide Camera supports DepthData: false
-- Back Camera supports DepthData: false
-- Front Camera supports DepthData: false
附言从历史上看,前置摄像头的质量往往低于后置摄像头,但在深度捕捉方面,您无法击败使用红外投影仪/扫描仪的 TrueDepth 摄像头。
既然您知道哪些相机可以完成这项工作,您需要选择功能强大的相机并启用深度:
(空行是代码省略,这不是一个完整的例子)
// this is in your 'post-select-camera' initialization
_captureSession = [[AVCaptureSession alloc] init];
// cameraName is not the localizedName
_captureDevice = [AVCaptureDevice deviceWithUniqueID:cameraName];
// this is in your camera controller initialization
// enable depth delivery in AVCapturePhotoOutput
_capturePhotoOutput = [AVCapturePhotoOutput new];
[_captureSession addOutput:_capturePhotoOutput];
// BOOL depthDataSupported is a property of the controller
_depthDataSupported = [_capturePhotoOutput isDepthDataDeliverySupported];
if (_depthDataSupported) {
[_capturePhotoOutput setDepthDataDeliveryEnabled:YES];
}
[_captureSession addOutput:_capturePhotoOutput];
// this is in your capture method
// enable depth delivery in AVCapturePhotoSettings
AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings];
if (@available(iOS 11.0, *) && _depthDataSupported) {
[settings setDepthDataDeliveryEnabled:YES];
}
// Here I use a try/catch because even depth capable and enabled cameras can crash if settings are not correct.
// For example a very high picture resolution seems to throw an exception, and this might be a different limit for different phone models.
// I am sure this information is somewhere I haven't looked yet.
@try {
[_capturePhotoOutput capturePhotoWithSettings:settings delegate:photoDelegate];
} @catch (NSException *e) {
[settings setDepthDataDeliveryEnabled:NO];
[_capturePhotoOutput capturePhotoWithSettings:settings delegate:photoDelegate];
}
// after you took a photo and
// didFinishProcessingPhoto:(AVCapturePhoto *)photo was invoked
AVDepthData *depthData = [photo depthData];
if (depthData != nil) {
AVCameraCalibrationData *calibrationData = [depthData cameraCalibrationData];
CGFloat pixelSize = [calibrationData pixelSize];
matrix_float3x3 intrinsicMatrix = [calibrationData intrinsicMatrix];
CGSize referenceDimensions = [calibrationData intrinsicMatrixReferenceDimensions];
// now do what you need to do - I need to transform that to 16bit, Grayscale, Tiff, and it starts like this...
if (depthData.depthDataType != kCVPixelFormatType_DepthFloat16) {
depthData = [depthData depthDataByConvertingToDepthDataType:kCVPixelFormatType_DepthFloat16];
}
// DON'T FORGET HIT LIKE AND SUBSCRIBE FOR MORE BAD CODE!!! :P
}