【问题标题】:Realtime conversion of ARFrame.capturedImage CVPixelBufferRef to OpenCv MatARFrame.capturedImage CVPixelBufferRef 到 OpenCv Mat 的实时转换
【发布时间】:2018-11-15 01:12:18
【问题描述】:

ARKit 以 60 帧/秒的速度运行,相当于每帧 16.6 毫秒。

我当前将 CVPixelBufferRef (kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 格式) 转换为 cv::Mat (YCrCb) 的代码在 30 毫秒内运行,这会导致 ARKit 停止并且一切都滞后。

是否有人对如何更快地转换或我是否需要降低帧速率有任何想法?

有一个suggestion by Apple to use Metal,但我不知道该怎么做。

我也可以只取灰度平面,这是第一个通道,运行时间

【问题讨论】:

    标签: ios opencv arkit


    【解决方案1】:

    为了使用 Metal 处理像素缓冲区中的图像,您需要执行以下操作。

    1. 调用 CVMetalTextureCacheCreateTextureFromImage 在像素缓冲区之上创建 CVMetalTexture 对象。
    2. 调用 CVMetalTextureGetTexture 创建一个 MTLTexture 对象,Metal 代码 (GPU) 可以读取和写入该对象。
    3. 编写一些金属代码来转换颜色格式。

    我有一个开源项目 (https://github.com/snakajima/vs-metal),它使用 Metal 处理像素缓冲区(来自相机,而不是 ARKit)。随意复制此项目中的任何代码。

    【讨论】:

      【解决方案2】:

      我尝试将 Ycbcr 转换为 RGB,在 RGB mat 中进行图像处理并将其转换回 Ycbcr,它工作得非常缓慢。我建议只使用静态图像。对于实时处理,我们应该直接在 cv::Mat 中处理。 ARFrame.capturedImage 是 Ycbcr 缓冲区。所以,解决方案是

      1. 将缓冲区分散到 2 个 cv::Mat(yPlane 和 cbcrPlane)。请记住,我们不会克隆内存,我们会创建 2 个 cv::Mat,其基地址是 yPlane 地址和 cbcrPlane 地址。
      2. 在 yPlane 和 cbcrPlane 上进行图像处理,size(cbcrPlane) = size(yPlane) / 2。

      你可以在这里查看我的代码:https://gist.github.com/ttruongatl/bb6c69659c48bac67826be7368560216

      【讨论】:

      • 我不知道如何转换为 RGBA。你能帮我解决这个问题吗?
      • 是否可以创建一个包含所有信息的 Mat 而不是两个 Mats yPlane 和 cbcrPlane?
      • 两个 Mats yPlane 和 cbcrPlane 帮助我们的代码更清晰。正如我所说,我们不会克隆内存。您可能需要再编写一个函数来将 RGB 转换为 RGBA。
      猜你喜欢
      • 2013-10-21
      • 2014-10-21
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多