8

我正在构建一个使用CIAreaHistogramCore Image 过滤器的应用程序。我使用inputCount10 的值(桶数)进行测试,使用inputScale1 的值。

我得到了CIImage直方图本身的 ,然后我通过一个自定义内核(见帖子结尾)将 alpha 值设置为 1(否则直方图计算中的 alpha 值是预乘的),然后将其转换为NSBitmapImageRep.

然后我扫描图像代表的缓冲区并打印 RGB 值(跳过 alpha 值)。但是,当我这样做时,10 个中 R、G 和 B 值的总和不一定等于 255。

例如,对于全黑图像,我应用直方图,然后应用自定义内核,并获得以下输出:

RGB: 255 255 255
RGB: 0 0 0
RGB: 0 0 0
RGB: 0 0 0
RGB: 0 0 0
RGB: 0 0 0
RGB: 0 0 0
RGB: 0 0 0
RGB: 0 0 0
RGB: 0 0 0

这正如我所料,因为所有像素都是黑色的,所以一切都在第一个桶中。但是,如果我对彩色图像运行相同的算法,我会得到以下结果:

RGB: 98 76 81
RGB: 164 97 87
RGB: 136 161 69
RGB: 100 156 135
RGB: 80 85 185
RGB: 43 34 45
RGB: 31 19 8
RGB: 19 7 3
RGB: 12 5 2
RGB: 16 11 11

将 R、G 和 B 的值相加 - 它们加起来不等于 255。这会导致问题,因为我需要比较其中两个直方图,而我的算法预计总和在 0 到 255 之间。我显然可以缩放这些值,但出于性能原因,我想避免额外的步骤。

我注意到其他一些有趣的事情可能会提供一些关于为什么会发生这种情况的线索。在我的自定义内核中,我只是将 alpha 值设置为 1。我尝试了第二个内核(见帖子末尾),它将所有像素设置为红色。显然,绿色和蓝色值为零。但是,在检查位图代表的值时,我得到了这个结果:

RGB: 255 43 25

但我只是将 G 和 B 设置为零!这似乎是问题的一部分,这表明色彩管理。但是由于我在内核中明确设置了值,因此只有一个代码块可以发生这种情况 - 从过滤器的 CIImage 转换为 NSBitmapImageRep:

NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCIImage:kernelOutput];
unsigned char *buf = [bitmapRep bitmapData];

一旦我将像素设置为 RGB 255 0 0,然后执行这些行,然后读取缓冲区,RGB 值都是 255 43 25。我进一步尝试设置整个工作流程所基于的原始 CGImageRef 的颜色空间kCGColorSpaceGenericRGB,认为颜色配置文件可能正在执行,但无济于事。

谁能告诉我为什么CIFilter内核会以这种方式运行,以及如何解决它?

如前所述,这里是我使用的 CIFilter 内核函数的副本。首先,将 alpha 设置为 1 的那个:

kernel vec4 adjustHistogram(sampler src)
{
    vec4 pix = sample(src, destCoord());
    pix.a = 1.0;
    return pix;
}

接下来,将所有像素设置为 RGB 255 0 0 但一旦转换为 255 43 25 就结束了NSBitmapImageRep

kernel vec4 adjustHistogram(sampler src)
{
    vec4 pix = sample(src, destCoord());
    pix.r = 1.0; pix.g = 0.0; pix.b = 0.0;
    pix.a = 1.0;
    return pix;
}

在此先感谢您的帮助。

4

1 回答 1

0

在使用自定义 Core Image 过滤器时(或者当您创建新的 CIImage 对象或替换现有对象时),您只需要一行代码即可生成和显示直方图:

return [CIFilter filterWithName:@"CIHistogramDisplayFilter" keysAndValues:kCIInputImageKey, self.inputImage, @"inputHeight", @100.0, @"inputHighLimit", @1.0, @"inputLowLimit", @0.0, nil].outputImage;
于 2015-07-19T09:44:25.867 回答