Vous devez écrire votre propre en utilisant Core Image noyau Langue et CIColorKernel
.
J'utiliserais un smoothstep
et passerais deux valeurs de bord avec la luminance du pixel courant. Le CIKL pourrait ressembler à ceci:
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);
}
Vous pouvez envelopper cela dans un CIFilter
avec le code suivant:
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)
}
}
Notez que vous devez vous assurer inputEdge0
est inférieure à inputEdge1
, ou smoothstep
ira un peu fou. Vous pouvez les saturate
aussi, pour assurer qu'ils sont entre 0 et 1.
Jetez un oeil à CIFilter.registerFilterName
qui vous permettra de créer une instance de SmoothThreshold
avec la syntaxe familière, bien que cela fonctionne très bien:
let image = CIImage(image: UIImage(named: "monalisa.jpg")!)!
let filter = SmoothThreshold()
filter.inputImage = image
let final = filter.outputImage
À la votre!
Simon
Merci! J'étais surtout intéressé par l'algorithme puisque je suis familier avec la création de noyaux. Pourquoi comparez-vous le canal luma? (Je ne suis intéressé qu'à comparer la moyenne des valeurs RGB mais je suis toujours curieux quant à la raison derrière luma). – joelg
Dépend du cas d'utilisation: si le seuil est défini par la luminosité perçue, le calcul de la moyenne n'est pas tout à fait correct. Le vert pur (0,1,0) est beaucoup plus clair que le bleu pur (0,0,1) mais a les mêmes valeurs moyennes. –
Ouais, c'est tout à fait logique. À la fin de la journée, j'essayais juste d'accomplir ce qui est décrit ici: https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29 – joelg