2016-10-08 3 views
0

Ich werde eine Matrix auf ein CGImage mit Accelerate-Framework anwenden.Wie verwende ich vImageMatrixMultiply in Swift 3?

Zuerst konvertiert ich eine CGImage zu 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)) 

dann versucht vImageMatrixMultiply anzuwenden.

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

Aber vImageMatrixMultiply nicht akzeptiert vImage_Buffer als SRCs und dests Argumente, und ich bekam einen Übersetzungsfehler beschreiben:

Wert kann nicht vom Typ umwandeln "vImage_Buffer" zu erwarten Argument Typ „UnsafePointer < vImage_Buffer >? "

Ich suchte nach Umwandlung "vImage_Buffer" in "UnsafePointer < vImage_Buffer>?" aber habe keine Antwort gefunden.

Also ich würde gerne wissen, wie "vImage_Buffer" auf "UnsafePointer < vImage_Buffer>?", Konvertieren oder wie direkt erstellen "UnsafePointer < vImage_Buffer>?" von CGImage oder anderen Möglichkeiten, vImageMatrixMultiply entsprechend zu verwenden.

Antwort

0

verwendet habe ich nicht vImageMatrixMultiply_PlanarF, sondern nach der Header-Dokumentation und der Funktionssignatur, müssen Sie Verweise auf mehr vImage_Buffer s für die ersten beiden Parameter zu übergeben, srcs und dests.

Wenn Sie mehrere Werte über UnsafeMutablePointer<T> übergeben müssen, deklarieren Sie normalerweise eine Variable [T], und übergeben Sie es als ein Inout-Argument.

In Ihrem Fall T = UnsafePointer<vImage_Buffer>?, so müssen Sie eine Variable des Typs [UnsafePointer<vImage_Buffer>?] deklarieren. Und jeder Zeiger im Array muss eine entsprechend vorbereitete vImage_Buffer zeigen.

Der alte Code in dieser Antwort AKTUALISIERT with... Methoden in einer schlechten Art und Weise verwendet hat. Bitte versuchen Sie es mit dem aktualisierten Code.


So können Sie so etwas schreiben müssen:

//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) 
      ) 
     } 
    } 
+0

Sie sehr viel für den Code danken. Es ist viel komplizierter als ich dachte ... – rdeepy

+0

@rdeepy, in der Tat habe ich sehr kleinen Teil von Accelerate Framework jemals verwendet, aber das ist schwieriger als alle anderen, die ich erlebt habe. Und wenn Sie wirklich einige Teile des obigen Codes übernehmen, sagen Sie es mir bitte. Sie brauchen etwas Fertigstellungscode nach der Verwendung ... – OOPer

+0

Vielen Dank. Ich habe vDSP benutzt, aber es war das erste Mal, dass ich vImage nutze. Ich begann Core Image zu überprüfen und jetzt denke ich, dass CIColorMatrix meine Anforderung leichter erfüllen wird. – rdeepy

Verwandte Themen