如何为CoreImage编写类似直方图的内核过滤器?

时间:2016-07-22 16:14:05

标签: ios swift histogram core-image

在内核例程规则的文档中,它说'内核例程通过使用反向映射回输入图像的相应像素来计算输出像素。虽然你可以用这种方式表达大多数像素计算 - 比其他人更自然地表达 - 但是有一些图像处理操作,即使不是不可能,也很难。例如,计算直方图很难描述为与源图像的逆映射。'

然而,苹果显然是以某种方式这样做,因为他们确实有一个CIAreaHistogram核心图像过滤器就是这样做的。

我可以看到一种理论上的方法来实现这个限制:

假设你想要一个256元素的红色通道直方图......

您有一个256x1像素的输出图像。为这256个像素中的每个像素调用内核函数。每次调用时,内核函数都必须在整个图像中读取每个像素,检查该像素的红色值是否与该存储桶匹配并递增计数器。当它处理整个图像中该输出像素的每个像素时,它除以像素总数并将该输出像素值设置为该计算值。问题是,假设它确实有效,这是非常低效的,因为每个输入像素被访问256次,尽管每个输出像素只写一次。

最佳的方法是内核迭代每个INPUT像素,让我们根据该值更新任何输出像素。然后输入像素将只读取一次,输出像素将被读取和写入总共(输入宽度)x(输入高度)次。

有没有人知道如何让这种过滤器工作?很明显苹果公司提供了一个可用于直方图的过滤器,但我需要它来做一个更有限的直方图形式。 (例如,蓝色直方图仅限于在给定范围内具有红色值的样本。)

1 个答案:

答案 0 :(得分:1)

这个问题是Core Image中的自定义内核代码就像一个逐像素重映射的函数。除了你当前正在计算的像素之外,你实际上并没有大量的信息。自定义核心图像过滤器就像这样

for i in 1 ... image.width
    for j in 1 ... image.height
        New_Image[i][j] = CustomKernel(Current_Image[i][j])
    end
end

实际上,通过自定义内核制作自己的直方图并不合理,因为除了已经制作的CustomKernel函数之外,你实际上没有对新图像的任何控制。这实际上是为iOS10创建CIImageProcessor的原因之一,您可能更容易通过该功能制作直方图(并通过图像处理产生其他很酷的影响),我建议查看WWDC 2016年视频(原始图像和实时图像会话)。

IIRC,如果你真的想要制作直方图,它仍然可以,但你必须使用UIImage版本,然后将生成的图像转换为RBG图像,你可以对其进行计数和存储他们在垃圾箱里。我会推荐Simon Gladman的书,因为他有一章专门讨论直方图,但是核心图像默认版本还有很多,因为他们对图像的控制比我们使用框架更多。