Вам нужно будет написать свой собственный, используя Core, образ ядра языка и CIColorKernel
.
Я бы использовал smoothstep
и передал два значения по краю вместе с яркостью текущего пикселя. CIKL может выглядеть примерно так:
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);
}
Вы можете обернуть это в CIFilter
со следующим кодом:
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)
}
}
Обратите внимание, что вам необходимо обеспечить inputEdge0
меньше inputEdge1
, или в smoothstep
будет немного сумасшедшим. Вы можете saturate
их тоже, чтобы убедиться, что они между 0 и 1.
Посмотрите CIFilter.registerFilterName
, который позволит вам создать экземпляр SmoothThreshold
с знакомым синтаксисом, хотя это будет работать нормально:
let image = CIImage(image: UIImage(named: "monalisa.jpg")!)!
let filter = SmoothThreshold()
filter.inputImage = image
let final = filter.outputImage
Приветствия!
Simon
Спасибо! Меня больше интересовал алгоритм, так как я знаком с созданием ядер. Почему вы сравниваете канал яркости? (Меня интересует только сравнение средних значений RGB, но мне все еще интересно узнать о причине яркости). – joelg
Зависит от варианта использования: если это пороговое значение по воспринимаемой яркости, усреднение не совсем корректно. Чистый зеленый (0,1,0) намного ярче, чем чистый синий (0,0,1), но имеет одинаковые средние значения. –
Да, общий смысл. В конце дня я просто пытался выполнить то, что описано здесь: https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29 – joelg