2016-03-29 28 views

cevap

6

Kendi kullanarak Core Image Çekirdek Dili yazmak gerekir ve bir CIColorKernel.

smoothstep kullanırım ve geçerli pikselin parlaklığı ile birlikte iki kenar değerini geçiririm.

Eğer inputEdge0 sağlamak gerekir
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) 
    } 
} 

Not inputEdge1 daha azdır, ya da:

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); 
} 

Aşağıdaki kodu içeren bir CIFilter içine bu sarabilirsiniz: CIKL şuna benzer olabilir smoothstep biraz çılgın olacak.

: Bu iyi çalışır karşın, tanıdık sözdizimi ile SmoothThreshold bir örneğini oluşturmak sağlayacak CIFilter.registerFilterName göz at 0 ile

1. onlar konum sağlamak için, onları da saturate isteyebilirsiniz

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

let filter = SmoothThreshold() 
filter.inputImage = image 

let final = filter.outputImage 

Şerefe!

Simon

+0

Teşekkürler! Ben çekirdek yaratmaya aşina olduğumdan beri çoğunlukla algoritma ile ilgileniyordum. Neden luma kanalını karşılaştırıyorsun? (Sadece RGB değerlerinin ortalamasını karşılaştırmakla ilgileniyorum, ancak hala luma'nın arkasındaki nedene meraklıyım). – joelg

+1

Kullanım durumuna bağlı olarak: algılanan parlaklık ile eşleşiyorsa, ortalama alma tam olarak doğru değildir. Saf yeşil (0,1,0) çok daha parlaktır ve saf mavi (0,0,1) fakat aynı ortalama değerlere sahiptir. –

+0

Evet, tam anlam ifade ediyor. Günün sonunda, burada anlatılan şeyi başarmaya çalışıyorum: https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29 – joelg

1

Bu benim için çalışıyor sona erdi:

[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}"];