【问题标题】:Can I apply a CIFilter to ARkit camera feed?我可以将 CIFilter 应用于 ARkit 相机源吗?
【发布时间】:2017-11-21 08:06:27
【问题描述】:

我正在尝试对 ARSCNView 中的相机实时蒸汽图像应用模糊效果。我检查了 WWDC 视频。他们只提到了使用 Metal 进行自定义渲染,但我在网上没有找到任何完整的示例。知道该怎么做吗?


更新 1 我试图将过滤器应用于背景。它显示不正确的方向。我该如何解决这个问题?

let bg=self.session.currentFrame?.capturedImage

        if(bg != nil){
            let context = CIContext()
            let filter:CIFilter=CIFilter(name:"CIColorInvert")!
            let image:CIImage=CIImage(cvPixelBuffer: bg!)
            filter.setValue(image, forKey: kCIInputImageKey)
            let result=filter.outputImage!
            self.sceneView.scene.background.contents = context.createCGImage(result, from: result.extent)

        }

【问题讨论】:

  • 可能你可以在SceneKit中使用ScnTechnique的后期处理;我自己没有尝试过。 developer.apple.com/documentation/scenekit/scntechnique
  • 看起来直播图像被设置为场景背景,我不确定如何为其添加过滤器。您还可以通过 sceneView.session.currentFrame?.capturedImage 访问像素缓冲区,以便您可以对其应用过滤器并更新背景
  • @Guig 谢谢!是工作!我现在可以在后台应用一些 CIFilters 了!但是方向不对……
  • 如果你不介意摆弄 YCbCr 像素缓冲区,this solution works

标签: cifilter ios11 arkit


【解决方案1】:

我找到了一个很好的解决方案,即只要设备方向发生变化,只需对background 属性应用相应的几何变换:

func session(_ session: ARSession, didUpdate frame: ARFrame) {
    let image = CIImage(cvPixelBuffer: frame.capturedImage)
    filter.setValue(image, forKey: kCIInputImageKey)

    let context = CIContext()
    if let result = filter.outputImage,
        let cgImage = context.createCGImage(result, from: result.extent) {

        sceneView.scene.background.contents = cgImage
        if let transform = currentScreenTransform() {
            sceneView.scene.background.contentsTransform = transform
        }
    }
}

private func currentScreenTransform() -> SCNMatrix4? {
    switch UIDevice.current.orientation {
    case .landscapeLeft:
        return SCNMatrix4Identity
    case .landscapeRight:
        return SCNMatrix4MakeRotation(.pi, 0, 0, 1)
    case .portrait:
        return SCNMatrix4MakeRotation(.pi / 2, 0, 0, 1)
    case .portraitUpsideDown:
        return SCNMatrix4MakeRotation(-.pi / 2, 0, 0, 1)
    default:
        return nil
    }
}

确保首先在 viewDidLoad 方法中调用 UIDevice.current.beginGeneratingDeviceOrientationNotifications()

【讨论】:

  • 您好,我想在 ARKit 中使用 CIFilter 集成颜色过滤器,我已经尝试使用上面的代码,但是在运行时,输出被拉长了,我已经发布了,请看一下,@ 987654321@
【解决方案2】:

我遇到了同样的问题。你可以试试这个

let bg = sceneView.session.currentFrame?.capturedImage
    if (bg != nil) {
        let context = CIContext()
        let filter:CIFilter = CIFilter(name: "CIColorInvert")!

        let image:CIImage = CIImage(cvPixelBuffer: bg!, options: nil)

        let cgImage:CGImage = context.createCGImage(image, from: image.extent)!
        let uiImage:UIImage = UIImage.init(cgImage: cgImage)
        let resultImage = CIImage(image: uiImage)?.oriented(forExifOrientation: imageOrientationToDeviceOrientation(value: UIDevice.current.orientation))

        filter.setValue(resultImage, forKey: kCIInputImageKey)

        let result = filter.outputImage!
        self.sceneView.scene.background.contents = context.createCGImage(result, from: result.extent)
    }


func imageOrientationToDeviceOrientation(value: UIDeviceOrientation) -> Int32 {
            switch (value) {
            case .portrait:
                return 6
            case .landscapeLeft:
                return 1
            case .landscapeRight:
                return 3
            default:
                return 6
            }
        }

【讨论】:

  • 此解决方案有效,但在 iPhone7P 上运行缓慢
  • 我在iPhone 6、6S和7上测试过,没问题
  • 对我来说,iPhone7P 的帧时间从 2ms 飙升到 20ms。你的尺寸是多少?
  • 你是如何测量的?
  • in viewDidLoad set self.sceneView.showsStatistics = YES; link 然后运行应用程序并点击“+”打开它
猜你喜欢
  • 2019-05-22
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 2018-02-17
相关资源
最近更新 更多