2016-03-29 2 views
2

スムーズなしきい値として使用できる既存のフィルタはありますか?これにより、ピクセル値は2つの値の間でしきい値を設定する必要がありますが、中間値は補間されます。CoreImageを使用してスムーズなしきい値フィルタを作成するにはどうすればよいですか?

基本的に、私はこれを実装しようとしています:

https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29

答えて

6

あなたがあなた自身の使用コアイメージカーネル言語を記述する必要がありますCIColorKernel

私はsmoothstepを使用し、現在のピクセルの輝度とともに2つのエッジ値を渡します。あなたはinputEdge0未満inputEdge1であることを確認する必要があり、またはます

class SmoothThreshold: CIFilter 
{ 
    var inputImage : CIImage? 
    var inputEdgeO: CGFloat = 0.25 
    var inputEdge1: CGFloat = 0.75 

    var colorKernel = CIColorKernel(string: 
     "kernel vec4 color(__sample pixel, float inputEdgeO, float inputEdge1)" + 
     "{" + 
     " float luma = dot(pixel.rgb, vec3(0.2126, 0.7152, 0.0722));" + 
     " float threshold = smoothstep(inputEdgeO, inputEdge1, luma);" + 
     " return vec4(threshold, threshold, threshold, 1.0);" + 
     "}" 
    ) 

    override var outputImage: CIImage! 
    { 
     guard let inputImage = inputImage, 
      colorKernel = colorKernel else 
     { 
      return nil 
     } 

     let extent = inputImage.extent 
     let arguments = [inputImage, 
         inputEdgeO, 
         inputEdge1] 

     return colorKernel.applyWithExtent(extent, 
              arguments: arguments) 
    } 
} 

注:次のコードでCIFilterにこれをラップすることができます

kernel vec4 color(__sample pixel, float inputEdgeO, float inputEdge1) 
{ 
    float luma = dot(pixel.rgb, vec3(0.2126, 0.7152, 0.0722)); 
    float threshold = smoothstep(inputEdgeO, inputEdge1, luma); 
    return vec4(threshold, threshold, threshold, 1.0); 
} 

:CIKLはこのような何かを見ることができますsmoothstep少し狂って行くだろう。

を:これは正常に動作しますが、あなたは、あなたが使い慣れた構文で SmoothThresholdのインスタンスを作成することができます CIFilter.registerFilterNameを見てください0〜

1.彼らがしていることを確認するために、あまりにもそれらをsaturateすることもできます

let image = CIImage(image: UIImage(named: "monalisa.jpg")!)! 

let filter = SmoothThreshold() 
filter.inputImage = image 

let final = filter.outputImage 

乾杯!

シモン

+0

ありがとう!カーネルの作成に慣れてきたので、私はアルゴリズムにほとんど興味がありました。あなたはなぜルマチャンネルを比較しますか? (私はRGB値の平均値を比較することにのみ関心がありますが、私はまだlumaの背後にある理由について興味があります)。 – joelg

+1

ユースケースに依存します:知覚される明るさによって閾値処理される場合、平均化は正しくはありません。純粋な緑(0,1,0)は、純粋な青(0,0,1)よりもはるかに明るいですが、同じ平均値を持ちます。 –

+0

ええ、全然意味があります。終わりには、ここで説明されていることを達成しようとしていました。https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29 – joelg

1

これは私のために働くことになった:

[CIColorKernel kernelWithString: 
       @"kernel vec4 threshold(__sample s, float thresh) {\n" 
       "float avg = (s.r + s.g + s.b)/3.0;\n" 
       "float val = smoothstep(0.0, thresh, avg);" 
       "return vec4(val, val, val, 1.0);\n}"]; 
関連する問題