swift - 如何在 Swift 3 中使用 vImageMatrixMultiply?

标签 swift accelerate-framework vimage

我将使用 Accelerate 框架将矩阵应用于 CGImage。

首先,我将 CGImage 转换为 vImage_Buffer,

let bitmapInfo: CGBitmapInfo = [ .floatComponents,
                                 CGBitmapInfo( rawValue: CGImageAlphaInfo.none.rawValue ),
                                 .byteOrder32Little ]

var format = vImage_CGImageFormat( bitsPerComponent: 32,
                                   bitsPerPixel: 32 * 3,
                                   colorSpace: nil,
                                   bitmapInfo: FloatBitmapInfo,
                                   version: 0,
                                   decode: nil,
                                   renderingIntent: .defaultIntent )

var inputBuffer = vImage_Buffer()

vImageBuffer_InitWithCGImage( &inputBuffer,
                              &format,
                              nil,
                              aCGImage,             // input CGImage
                              UInt32( kvImageNoFlags ) )

然后尝试应用 vImageMatrixMultiply。

vImageMatrixMultiply_PlanarF( &inputBuffer,         // srcs
                              &outputBuffer,        // dests
                              3,                    // src_planes
                              3,                    // dest_planes
                              aMatrix,              // applying matrix
                              &preBias,             // pre_bias
                              &postBias,            // post_bias
                              UInt32( kvImageNoFlags ) )

但是 vImageMatrixMultiply 不接受 vImage_Buffer 作为 srcs 和 dests 参数,并且我收到一个编译错误,描述:

Cannot convert value of type "vImage_Buffer" to expected argument type "UnsafePointer< vImage_Buffer >?"

我搜索了有关将“vImage_Buffer”转换为“UnsafePointer< vImage_Buffer >?”的信息但还没有找到任何答案。

所以我想知道如何将“vImage_Buffer”转换为“UnsafePointer< vImage_Buffer >?”,或者如何直接创建“UnsafePointer< vImage_Buffer >?”来自 CGImage,或任何其他适当使用 vImageMatrixMultiply 的方法。

最佳答案

我没有使用过vImageMatrixMultiply_PlanarF ,但根据 header 文档和函数签名,您需要将指针传递给多个 vImage_Buffer s 代表前两个参数,srcsdests .

当需要通过 UnsafeMutablePointer<T> 传递多个值时,通常声明一个变量 [T] ,并将其作为 inout 参数传递。

就您而言T =UnsafePointer<vImage_Buffer>? ,所以你需要声明一个 [UnsafePointer<vImage_Buffer>?] 类型的变量。 并且数组中包含的每个指针都需要指向一个适当准备的vImage_Buffer .

已更新 此答案中的旧代码使用 with...方法不当。请尝试使用更新的代码。

<小时/>

因此,您可能需要编写如下内容:

    //Prepare 3 vImage_Buffers for source planes
    //(vImageConvert_RGBFFFtoPlanarF)
    //You are responsible for filling out the height, width, and rowBytes fields of this structure, and for allocating a data buffer of the appropriate size.
    let inputBuffers: [vImage_Buffer] = (0...2).map {_ in
        var imageBuf = vImage_Buffer()
        imageBuf.width = inputBuffer.width
        imageBuf.height = inputBuffer.height
        imageBuf.rowBytes = Int(imageBuf.width) * MemoryLayout<Float>.size
        imageBuf.data = malloc(imageBuf.rowBytes * Int(imageBuf.height))
        return imageBuf
    }

    //Prepare 3 vImage_Buffers for destination planes
    //(vImageMatrixMultiply_PlanarF)
    //You are responsible for filling out the height, width, and rowBytes fields of these structures, and for allocating data buffers of the appropriate size.
    let outputBuffers: [vImage_Buffer] = (0...2).map {_ in
        var imageBuf = vImage_Buffer()
        imageBuf.width = inputBuffer.width
        imageBuf.height = inputBuffer.height
        imageBuf.rowBytes = Int(imageBuf.width) * MemoryLayout<Float>.size
        imageBuf.data = malloc(imageBuf.rowBytes * Int(imageBuf.height))
        return imageBuf
    }

    //`aMatrix` needs to hold `src_planes`x`dest_planes` elements
    let aMatrix: [Float] = [0.5, 0.25, 0.25,  0.25, 0.5, 0.25, 0.25, 0.25, 0.5]
    var preBias: Float = 0.0
    var postBias: Float = 0.0
    //You need to use pointers or BufferPointers inside the closure, should not take them out of the closure
    inputBuffers.withUnsafeBufferPointer {inputBuffersBP in
        outputBuffers.withUnsafeBufferPointer {outputBuffersBP in
            //Prepare pointer array pointing each vImage_Buffer
            var inputBufferPointers: [UnsafePointer<vImage_Buffer>?] =
                inputBuffers.withUnsafeBufferPointer {inputBuffersBP in
                    (0...2).map{inputBuffersBP.baseAddress! + $0}
            }
            //If you want to use PlanarF format, you need to split RGB into distict vImage_Buffers
            vImageConvert_RGBFFFtoPlanarF(
                &inputBuffer,
                inputBufferPointers[0]!,
                inputBufferPointers[1]!,
                inputBufferPointers[2]!,
                UInt32(kvImageNoFlags)
            )
            //Prepare pointer array pointing each vImage_Buffer
            var outputBufferPointers: [UnsafePointer<vImage_Buffer>?] =
                outputBuffers.withUnsafeBufferPointer {outputBuffersBP in
                    (0...2).map{outputBuffersBP.baseAddress! + $0}
            }
            //All these things prepared properly, you can call `vImageMatrixMultiply_PlanarF` like this...
            vImageMatrixMultiply_PlanarF(
                &inputBufferPointers,         // srcs
                &outputBufferPointers,        // dests
                3,                    // src_planes
                3,                    // dest_planes
                aMatrix,              // applying matrix
                &preBias,             // pre_bias
                &postBias,            // post_bias
                UInt32(kvImageNoFlags)
            )
        }
    }

关于swift - 如何在 Swift 3 中使用 vImageMatrixMultiply?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39928524/

相关文章:

ios - 加速框架 FFT vDSPztoc split real form to split real vector

iphone - 我想在 iOS 中实现图像处理算法,你能推荐一些好的入门指南吗

ios - 如何使用加速框架(vImage)缩放灰度图像

ios - Accelerate 的 vImage 与 vDSP

ios - 文本字段中的 swift 3 tableView 复制自身

ios - view.center 命令后 subview 框架未更新

swift - Swift 3 中的通用类型别名?

swift - 如何快速解析特定标签

python - 为什么 Swift 中的 FFT 与 Python 中的不同?

swift - 转换为 vImage 的 CMSampleBuffer 帧颜色错误