ios - 从 ARCamera 设置 VNImageOptionCameraIntrinsics

标签 ios objective-c arkit coreml

我正在构建一个将 ARKit 与 CoreML 结合起来的应用程序。我使用以下几行将帧传递给 VNImageRequestHandler:

// the frame of the current Scene
CVPixelBufferRef pixelBuffer = _cameraPreview.session.currentFrame.capturedImage;

NSMutableDictionary<VNImageOption, id> *requestOptions = [NSMutableDictionary dictionary];
VNImageRequestHandler *handler = [[VNImageRequestHandler alloc] initWithCVPixelBuffer:pixelBuffer options:requestOptions];

注意requestOptions。它应包含将相机内部函数传递给 CoreML 的 VNImageOptionCameraIntrinsics 字段。

在使用 ARKit 之前,我使用 CMSampleBufferRef 从相机获取图像。可以使用以下命令检索和设置内在函数:

CFTypeRef cameraIntrinsicData = CMGetAttachment(sampleBuffer, kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, nil);
requestOptions[VNImageOptionCameraIntrinsics] = (__bridge id)(cameraIntrinsicData);

但是,我现在使用的是 ARFrame,但我仍然想设置正确的内在函数,因为 pixelBuffer 已旋转。

查看文档:

https://developer.apple.com/documentation/vision/vnimageoption?language=objc

https://developer.apple.com/documentation/arkit/arcamera/2875730-intrinsics?language=objc

我们可以看到 ARCamera 也提供了内部函数,但是,如何在 requestOptions 中正确设置该值?

到目前为止应该是这样的:

ARCamera *camera = _cameraPreview.session.currentFrame.camera;
NSMutableDictionary<VNImageOption, id> *requestOptions = [NSMutableDictionary dictionary];
// How to put camera.intrinsics here?
requestOptions[VNImageOptionCameraIntrinsics] = camera.intrinsics;

最佳答案

Giovanni评论中提到,将 UIDeviceOrientation 转换为 CGImagePropertyOrientation 可以避免使用 VNImageOptionCameraIntrinsics:

Utils.m

+(CGImagePropertyOrientation) getOrientation {
    CGImagePropertyOrientation orientation;
    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
    switch (deviceOrientation) {
        case UIDeviceOrientationPortrait:
            orientation = kCGImagePropertyOrientationRight;
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            orientation = kCGImagePropertyOrientationLeft;
            break;
        case UIDeviceOrientationLandscapeLeft:
            orientation = kCGImagePropertyOrientationUp;
            break;
        case UIDeviceOrientationLandscapeRight:
            orientation = kCGImagePropertyOrientationDown;
            break;
        default:
            orientation = kCGImagePropertyOrientationRight;
            break;
    }
    return orientation;
}

ViewController.mm

- (void)captureOutput {
    ARFrame *frame = self.cameraPreview.session.currentFrame;
    CVPixelBufferRef pixelBuffer = frame.capturedImage;

    CGImagePropertyOrientation deviceOrientation = [Utils getOrientation];
    NSMutableDictionary<VNImageOption, id> *requestOptions = [NSMutableDictionary dictionary];

    VNImageRequestHandler *handler = [[VNImageRequestHandler alloc] initWithCVPixelBuffer:pixelBuffer orientation:deviceOrientation options:requestOptions];

    [handler performRequests:@[[self request]] error:nil];
}

关于ios - 从 ARCamera 设置 VNImageOptionCameraIntrinsics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52140731/

相关文章:

ios - Swift - 如何在 MVC 中正确构建按钮?

ios - 谷歌和 Facebook Firebase Auth 使用 swift 3

iphone - 在 iPhone 中获取地址信息

ios - 使arkit相机垂直而不是水平

ios - 从 segue 返回时,UITableViewCells 不会取消选择

java - 如何在将一个页面导航到另一页面时发布 CODENAMEONE 表单(包括其所有组件)?

php - php返回的数据为空,iOS

iphone - 如何在 objective-c 中每 24 小时更新一次应用程序

swift - 在 ARKit 的 SCNPlane 上使用 GPUImage 对视频进行颜色键控

ios - 如何根据用户位置重新调整 SKNodes