自适应阈值 CIKernel/CIFilter iOS
Adaptive Threshold CIKernel/CIFilter iOS
我进行了全面研究,以找到一个对 iOS 执行自适应阈值处理的内核。不幸的是,我不了解内核语言或其背后的逻辑。下面,我找到了一个执行阈值处理的例程 (https://gist.github.com/xhruso00/a3f8a9c8ae7e33b8b23d)
static NSString * const kKernelSource = @"kernel vec4 thresholdKernel(sampler image)\n"
"{\n"
" float inputThreshold = 0.05;\n"
" float pass = 1.0;\n"
" float fail = 0.0;\n"
" const vec4 vec_Y = vec4( 0.299, 0.587, 0.114, 0.0 );\n"
" vec4 src = unpremultiply( sample(image, samplerCoord(image)) );\n"
" float Y = dot( src, vec_Y );\n"
" src.rgb = vec3( compare( Y - inputThreshold, fail, pass));\n"
" return premultiply(src);\n"
"}";
是否可以将其重写为自适应阈值内核?我提供给它的图像已经变成了黑白并且已经模糊了。你有什么资源可以指点我吗?我想坚持使用 CoreImage,因为我的整个堆栈都是围绕它构建的。
编辑:我试图实现的最佳示例/参考已在 GPUImage 的 GPUImageAdaptiveThresholdFilter 中实现 - https://github.com/BradLarson/GPUImage/blob/c5f0914152419437869c35e29858773b1a06083c/framework/Source/GPUImageAdaptiveThresholdFilter.m
这看起来如何:我使用了 CoreImage CIBoxBlur
(尽管专用卷积过滤器 可能 更快)并将其输出传递到我的 existing threshold filter.
class AdaptiveThresholdFilter: CIFilter
{
var inputImage : CIImage?
var thresholdKernel = CIColorKernel(string:
"kernel vec4 thresholdFilter(__sample image, __sample threshold)" +
"{" +
" float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" return vec4(vec3(step(imageLuma, thresholdLuma)), 1.0);" +
"}"
)
override var outputImage: CIImage!
{
guard let inputImage = inputImage,
thresholdKernel = thresholdKernel else
{
return nil
}
let blurred = inputImage.imageByApplyingFilter("CIBoxBlur",
withInputParameters: [kCIInputRadiusKey: 9])
let extent = inputImage.extent
let arguments = [inputImage, blurred]
return thresholdKernel.applyWithExtent(extent, arguments: arguments)
}
}
我找到了 this image 个阴影页面,代码如下:
let page = CIImage(image: UIImage(named: "son1.gif")!)
let filter = AdaptiveThresholdFilter()
filter.inputImage = page
let final = filter.outputImage
我得到了这个结果:
干杯!
西蒙
Simon 的过滤器是达到预期效果的正确方法,但是,您必须修改一些东西。
首先,调换imageLuma
和thresholdLuma
的顺序,因为我们希望黑色字母保持黑色而不是相反。此外,您应该添加一个常量(我选择 0.01
)来消除噪音。
var thresholdKernel = CIColorKernel(string:
"kernel vec4 thresholdFilter(__sample image, __sample threshold)" +
"{" +
" float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" return vec4(vec3(step(thresholdLuma, imageLuma+0.001)), 1);"
"}"
override var outputImage: CIImage! {
guard let inputImage = inputImage,
let thresholdKernel = thresholdKernel else {
return nil
}
let blurred = inputImage.applyingFilter("CIBoxBlur", withInputParameters: [kCIInputRadiusKey: 5]) // block size
let extent = inputImage.extent
let arguments = [inputImage, blurred]
return thresholdKernel.apply(withExtent: extent, arguments: arguments)
}
这就是您只使用 Apple 的 Core Image,而无需安装任何外部库的结果:)
当然,您可以尝试使用常量和块大小的值。
您可以使用 CIColorThresholdOtsu
核心图像过滤器
我进行了全面研究,以找到一个对 iOS 执行自适应阈值处理的内核。不幸的是,我不了解内核语言或其背后的逻辑。下面,我找到了一个执行阈值处理的例程 (https://gist.github.com/xhruso00/a3f8a9c8ae7e33b8b23d)
static NSString * const kKernelSource = @"kernel vec4 thresholdKernel(sampler image)\n"
"{\n"
" float inputThreshold = 0.05;\n"
" float pass = 1.0;\n"
" float fail = 0.0;\n"
" const vec4 vec_Y = vec4( 0.299, 0.587, 0.114, 0.0 );\n"
" vec4 src = unpremultiply( sample(image, samplerCoord(image)) );\n"
" float Y = dot( src, vec_Y );\n"
" src.rgb = vec3( compare( Y - inputThreshold, fail, pass));\n"
" return premultiply(src);\n"
"}";
是否可以将其重写为自适应阈值内核?我提供给它的图像已经变成了黑白并且已经模糊了。你有什么资源可以指点我吗?我想坚持使用 CoreImage,因为我的整个堆栈都是围绕它构建的。
编辑:我试图实现的最佳示例/参考已在 GPUImage 的 GPUImageAdaptiveThresholdFilter 中实现 - https://github.com/BradLarson/GPUImage/blob/c5f0914152419437869c35e29858773b1a06083c/framework/Source/GPUImageAdaptiveThresholdFilter.m
这看起来如何:我使用了 CoreImage CIBoxBlur
(尽管专用卷积过滤器 可能 更快)并将其输出传递到我的 existing threshold filter.
class AdaptiveThresholdFilter: CIFilter
{
var inputImage : CIImage?
var thresholdKernel = CIColorKernel(string:
"kernel vec4 thresholdFilter(__sample image, __sample threshold)" +
"{" +
" float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" return vec4(vec3(step(imageLuma, thresholdLuma)), 1.0);" +
"}"
)
override var outputImage: CIImage!
{
guard let inputImage = inputImage,
thresholdKernel = thresholdKernel else
{
return nil
}
let blurred = inputImage.imageByApplyingFilter("CIBoxBlur",
withInputParameters: [kCIInputRadiusKey: 9])
let extent = inputImage.extent
let arguments = [inputImage, blurred]
return thresholdKernel.applyWithExtent(extent, arguments: arguments)
}
}
我找到了 this image 个阴影页面,代码如下:
let page = CIImage(image: UIImage(named: "son1.gif")!)
let filter = AdaptiveThresholdFilter()
filter.inputImage = page
let final = filter.outputImage
我得到了这个结果:
干杯!
西蒙
Simon 的过滤器是达到预期效果的正确方法,但是,您必须修改一些东西。
首先,调换imageLuma
和thresholdLuma
的顺序,因为我们希望黑色字母保持黑色而不是相反。此外,您应该添加一个常量(我选择 0.01
)来消除噪音。
var thresholdKernel = CIColorKernel(string:
"kernel vec4 thresholdFilter(__sample image, __sample threshold)" +
"{" +
" float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" +
" return vec4(vec3(step(thresholdLuma, imageLuma+0.001)), 1);"
"}"
override var outputImage: CIImage! {
guard let inputImage = inputImage,
let thresholdKernel = thresholdKernel else {
return nil
}
let blurred = inputImage.applyingFilter("CIBoxBlur", withInputParameters: [kCIInputRadiusKey: 5]) // block size
let extent = inputImage.extent
let arguments = [inputImage, blurred]
return thresholdKernel.apply(withExtent: extent, arguments: arguments)
}
这就是您只使用 Apple 的 Core Image,而无需安装任何外部库的结果:)
当然,您可以尝试使用常量和块大小的值。
您可以使用 CIColorThresholdOtsu
核心图像过滤器