是否有现有的滤波器可以用作平滑阈值?我的意思是像素值应在两个值之间进行阈值处理,但中间值应进行插值。
基本上,我正在尝试实现这个:
https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29
是否有现有的滤波器可以用作平滑阈值?我的意思是像素值应在两个值之间进行阈值处理,但中间值应进行插值。
基本上,我正在尝试实现这个:
https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29
您需要使用Core Image Kernel语言和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
干杯!
西蒙
[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}"];