【问题标题】:Normalizing Disparity Image Using an Accelarator使用加速器归一化视差图像
【发布时间】:2020-03-10 17:48:45
【问题描述】:

我有一个视差图像,我正在使用下面的示例代码对其进行标准化,但它非常慢。 我需要使用一些加速器,如自定义 CIFilter 或任何其他技术,但我不知道怎么做?我目前正在使用 CIContext() 运行代码,它正在 CPU 上运行(不确定)。有没有办法在 GPU 上运行它并在没有自定义 CIfilter 的情况下加速? 这是当前代码:

extension CVPixelBuffer {

  func normalize() {

    let width = CVPixelBufferGetWidth(self)
    let height = CVPixelBufferGetHeight(self)

    CVPixelBufferLockBaseAddress(self, CVPixelBufferLockFlags(rawValue: 0))

    let baseAddr = CVPixelBufferGetBaseAddress(self)!
    let floatBuffer = unsafeBitCast(CVPixelBufferGetBaseAddress(self), to: UnsafeMutablePointer<Float>.self)

    var minPixel: Float = 1.0
    var maxPixel: Float = 0.0

    for y in 0 ..< height {
      for x in 0 ..< width {
        let pixel = floatBuffer[y * width + x]
        minPixel = min(pixel, minPixel)
        maxPixel = max(pixel, maxPixel)
      }
    }


    let range = maxPixel - minPixel

    for y in 0 ..< height {
      for x in 0 ..< width {
        let pixel = floatBuffer[y * width + x]
        floatBuffer[y * width + x] = (pixel - minPixel) / range
      }
    }

    CVPixelBufferUnlockBaseAddress(self, CVPixelBufferLockFlags(rawValue: 0))
  }
}

【问题讨论】:

    标签: swift core-image disparity-mapping


    【解决方案1】:

    您将像素值设为Float 值,因此您也可以使用 vDSP。

    vDSP_minvvDSP_maxv 计算极值,并且:

    floatBuffer[y * width + x] = (pixel - minPixel) / range
    

    可以替换为vDSP_vasm(您需要乘以range 的倒数)。

    查看执行此计算的 vDSP_normalize 也可能有用:

                m = sum(A[n], 0 <= n < N) / N;
                d = sqrt(sum(A[n]**2, 0 <= n < N) / N - m**2);
    
                if (C)
                {
                    // Normalize.
                    for (n = 0; n < N; ++n)
                        C[n] = (A[n] - m) / d;
                }
    

    【讨论】:

    • 我认为这是一个正确的答案,尽管不再需要它(我在使用 CIContext 的真实设备上运行我的代码并且速度足够快)。如果我将来需要额外的速度,我会使用你的代码。再次感谢您!
    【解决方案2】:

    对于您的用例,vImage 可能是最佳选择。请参阅this answer 中的选项 3。

    Core Image 中也有一些方法可以做到这一点。我会想象使用CIAreaMinMax 过滤器获取极值,然后使用一些巧妙的混合进行标准化。如果你愿意,我可以详细说明。

    【讨论】:

    • 感谢您的回答。是的,如果您提供代码示例将非常有用。
    • 我试图让它与内置的 CI 过滤器一起工作,但到目前为止没有运气。无论如何,使用 vImagevDSP 很可能是您的用例更快的选择。
    • 谢谢。我会的。
    【解决方案3】:

    我使用 Accelerate Framework vDSP 矢量函数来标准化视差。在 gitHub 中查看修改后的 PhotoBrowse 以获得工作演示。

    这是两个函数中的相关代码

    extension CVPixelBuffer {
        func vectorNormalize( targetVector: UnsafeMutableBufferPointer<Float>) -> [Float] {
            // range = max - min
            // normalized to 0..1 is (pixel - minPixel) / range
    
            // see Documentation "Using vDSP for Vector-based Arithmetic" in vDSP under system "Accelerate" documentation
    
            // see also the Accelerate documentation section 'Vector extrema calculation'
            // Maximium static func maximum<U>(U) -> Float
            //      Returns the maximum element of a single-precision vector.
    
            //static func minimum<U>(U) -> Float
            //      Returns the minimum element of a single-precision vector.
    
    
            let maxValue = vDSP.maximum(targetVector)
            let minValue = vDSP.minimum(targetVector)
    
            let range = maxValue - minValue
            let negMinValue = -minValue
    
            let subtractVector = vDSP.add(negMinValue, targetVector)
                // adding negative value is subtracting
            let result = vDSP.divide(subtractVector, range)
    
            return result
        }
    
        func setUpNormalize() -> CVPixelBuffer {
            // grayscale buffer float32 ie Float
            // return normalized CVPixelBuffer
    
            CVPixelBufferLockBaseAddress(self,
                                         CVPixelBufferLockFlags(rawValue: 0))
            let width = CVPixelBufferGetWidthOfPlane(self, 0)
            let height = CVPixelBufferGetHeightOfPlane(self, 0)
            let count = width * height
    
            let bufferBaseAddress = CVPixelBufferGetBaseAddressOfPlane(self, 0)
                // UnsafeMutableRawPointer
    
            let pixelBufferBase  = unsafeBitCast(bufferBaseAddress, to: UnsafeMutablePointer<Float>.self)
    
            let depthCopy  =   UnsafeMutablePointer<Float>.allocate(capacity: count)
            depthCopy.initialize(from: pixelBufferBase, count: count)
            let depthCopyBuffer = UnsafeMutableBufferPointer<Float>(start: depthCopy, count: count)
    
            let normalizedDisparity = vectorNormalize(targetVector: depthCopyBuffer)
    
            pixelBufferBase.initialize(from: normalizedDisparity, count: count)
                // copy back the normalized map into the CVPixelBuffer
    
            depthCopy.deallocate()
    //        depthCopyBuffer.deallocate()
    
            CVPixelBufferUnlockBaseAddress(self, CVPixelBufferLockFlags(rawValue: 0))
    
            return self
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 2015-09-05
      • 2015-01-12
      • 2021-09-11
      • 2018-08-16
      • 2015-01-15
      相关资源
      最近更新 更多