使用加速器归一化视差图像
Normalizing Disparity Image Using an Accelarator
我有一个视差图像,我正在使用下面的示例代码对其进行归一化,但速度非常慢。
我需要使用一些加速器(如自定义 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))
}
}
对于您的用例,vImage 可能是最佳选择。请参阅 this answer 中的选项 3。
在 Core Image 中也有一些方法可以做到这一点。我会想象使用 CIAreaMinMax
过滤器来获取极值,然后使用一些巧妙的混合来进行归一化。如果你愿意,我可以详细说明。
您的像素值是 Float
值,因此您也可以使用 vDSP。
vDSP_minv
and vDSP_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;
}
我使用 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
}
}
我有一个视差图像,我正在使用下面的示例代码对其进行归一化,但速度非常慢。 我需要使用一些加速器(如自定义 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))
}
}
对于您的用例,vImage 可能是最佳选择。请参阅 this answer 中的选项 3。
在 Core Image 中也有一些方法可以做到这一点。我会想象使用 CIAreaMinMax
过滤器来获取极值,然后使用一些巧妙的混合来进行归一化。如果你愿意,我可以详细说明。
您的像素值是 Float
值,因此您也可以使用 vDSP。
vDSP_minv
and vDSP_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;
}
我使用 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
}
}