2016-07-20 12 views
1

私は、指定されたピクセルとイメージ全体の違いをとるシンプルな(少なくとも私はそれは簡単だろうと思う)カスタムカーネルを書いています。 以下は私が持っているコードです。これはフィルタを作成するだけです。それは、遊び場で遊んで使うのは良いことです。コアイメージカーネル言語のOpenGL座標系

import UIKit 
import CoreImage 

let Flower = CIImage(image: UIImage(named: "flower.png")!)! 

class Test: CIFilter 
{ 
var inputImage1 : CIImage? 
var inputImage2 : CIImage? 

var kernel = CIKernel(string: 
"kernel vec4 colorRemap(sampler inputIm, sampler GaussIm)  " + 
"{                " + 
"vec4 size = samplerExtent(inputIm);       " + 
"float row = 1.0;            " + 
"float column = 1.0;           " + 
"float pixelx = (column - 1.0)/(size.w - 1.0)+1.0/(2.0*size.z);" + 
"float pixely = (size.z - row)/(size.z - 1.0)-1.0/(2.0*size.w);" + 
"vec3 g0 =sample(GaussIm,vec2(pixelx,pixely)).rgb;    " + 
"vec3 current = sample(inputIm,samplerCoord(inputIm)).rgb;  " + 
"vec3 diff =(current - g0);         " + 
"return vec4(diff,1.0);          " + 
"}                " 
) 
    var extentFunction: (CGRect, CGRect) -> CGRect = 
    { (a: CGRect, b: CGRect) in return CGRectZero } 
    override var outputImage: CIImage! 
{ 
    if let inputImage1 = inputImage1, 
     inputImage2 = inputImage2, 
     kernel = kernel 
    { 
     let extent = inputImage1.extent 
     let arguments = [inputImage1,inputImage2] 

     return kernel.applyWithExtent(extent, 
             roiCallback: 
      { (index, rect) in 
       return rect 

      }, 
      arguments: arguments) 

    } 
    return nil 
} 
} 

フィルタを使用するには、今、上記のコードでは、私は、我々は(1に位置する画素間の差分を取っていることを指定した以下の

let filter = Test() 
filter.inputImage1 = Flower 
filter.inputImage2 = Flower 
let output = filter.outputImage 

を行うことができます1)をGaussImの(通常の意味での)行列とinputImの全体像として扱っているかのように扱います。

周囲を遊んだ後、私はカスタムカーネル言語がOpenGLと同じように画像を扱うことに気がつきました。左下の角は(0,0)にマッピングされ、右上は(1,1)であるため、ピクセルの座標は0と1の間の数値になります。これで問題になるのは、違いを生かすために使います。

カーネルコードの最初の5行は、イメージ内の各ピクセル位置の中心を計算することによってこれを軽減しようとします。 OpenGLが画像をどのように扱っているかを考えているのか、それとももっと良い方法があるのか​​は分かりません。

私は下の画像で、上記のコードを実行した場合:私はXCodeので、次の取得 Input

OpenGL Output

さらに私はMATLABで同じことをすれば、私は次の取得出力: MATLAB Output

なぜ出力がMATLABと異なるのですか?それは私がカスタムフィルタから得ているものよりも少し暗いようですが、同時に同じ出力に近いです。私の考えは、カスタムカーネルがピクセル間で違いを取る方法でなければならないということでしたが、何が起こっているのかは分かりません。

答えて

0

私はこれを理解してしまいました。クリッピングの理由は、画像の計算方法の性質によるものです。この作業はコンテクストではなく、遊び場で行われたので、表示されたものは[0,1]の範囲にクリップされました。これを修正する方法は、計算を行うCIContextがオプションを使用して、計算で浮動小数点精度をサポートしていることを確認することでした。