【问题标题】:Set VNImageOptionCameraIntrinsics from ARCamera从 ARCamera 设置 VNImageOptionCameraIntrinsics
【发布时间】:2019-02-07 23:28:56
【问题描述】:

我正在构建一个将 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。它应该包含 VNImageOptionCameraIntrinsics 字段,该字段将相机内在函数传递给 CoreML。

在使用 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;

【问题讨论】:

    标签: ios objective-c arkit coreml


    【解决方案1】:

    正如 cmets 中提到的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];
    }
    

    【讨论】:

    • 谢谢!但是这是旧方法,您在此处使用示例缓冲区,请注意我想使用 ARFrame。
    • 啊,是的,很抱歉……我误读了您的意图。所以如果我理解正确,您不能将ARFrameVNImageOptionCameraInstrinsics 一起使用?
    • 没错。我想将有关 ARFrame/ARCamera 的正确信息传递给 VNImageRequestHandler。
    • @GiovanniTerlingen:Apple 有一个 sample project(不幸的是,我相信只有 Swift)可能有用。看来他们建议使用创建会话,然后使用方法 session:didUpdateFrame: 并将其传递给请求处理程序。
    • 谢谢!明天去看看。
    猜你喜欢
    • 1970-01-01
    • 2017-12-20
    • 2017-12-31
    • 2018-04-22
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 2021-05-05
    相关资源
    最近更新 更多