gpt4 book ai didi

objective-c - NSImage 的 CIAreaHistogram/CIHistogramDisplayFilter 工作示例

转载 作者:行者123 更新时间:2023-12-03 17:33:24 31 4
gpt4 key购买 nike

不知怎的,我无法弄清楚如何使用CIAreaHistogramCIHistogramDisplayFilter过滤器从NSImage输入中获取实际的、有意义的直方图图像。

我阅读了Apple的“核心图像过滤器引用”以及这里的相关帖子,但无论我尝试什么,我都没有得到任何有意义的输出。

这是我到目前为止的代码:

- (void) testHist3:(NSImage *)image {

CIContext* context = [[NSGraphicsContext currentContext] CIContext];

NSBitmapImageRep *rep = [image bitmapImageRepresentation];
CIImage *ciImage = [[CIImage alloc] initWithBitmapImageRep:rep];


ciImage = [CIFilter filterWithName:@"CIAreaHistogram" keysAndValues:kCIInputImageKey, ciImage, @"inputExtent", ciImage.extent, @"inputScale", [NSNumber numberWithFloat:1.0], @"inputCount", [NSNumber numberWithFloat:256.0], nil].outputImage;
ciImage = [CIFilter filterWithName:@"CIHistogramDisplayFilter" keysAndValues:kCIInputImageKey, ciImage, @"inputHeight", [NSNumber numberWithFloat:100.0], @"inputHighLimit", [NSNumber numberWithFloat:1.0], @"inputLowLimit", [NSNumber numberWithFloat:0.0], nil].outputImage;


CGImageRef cgImage2 = [context createCGImage:ciImage fromRect:ciImage.extent];
NSImage *img2 = [[NSImage alloc] initWithCGImage:cgImage2 size:ciImage.extent.size];

NSLog(@"Histogram image: %@", img2);
self.histImage = img2;


}

我得到的是一个 64x100 的图像,具有零表示(=不可见)。如果我使用以下命令创建 CI 上下文

CIContext *context = [[CIContext alloc] init];

然后生成的图像是灰色的,但至少它有一个表示:

Histogram image: <NSImage 0x6100002612c0 Size={64, 100} Reps=(
"<NSCGImageSnapshotRep:0x6100002620c0 cgImage=<CGImage 0x6100001a1880>>" )>

输入图像是 1024x768 JPEG 图像。

我对 Core Image 或 Core Graphics 缺乏经验,因此错误可能是转换回 NSImage 时......有什么想法吗?

<小时/>

编辑 2016-10-26:通过 rickster 非常全面的回答,我取得了很大的进步。

确实是 inputExtent 参数搞乱了我的结果。在那里提供一个CIVector解决了这个问题。我发现你也不能将其保留为默认值;我不知道默认值是什么,但它不是输入图像的完整尺寸。 (我通过过滤器运行图像及其镜像版本发现了这一点;我得到了不同的直方图。)

编辑2016-10-28:

所以,我现在有了一个可以工作、可显示的直方图;我的下一步将是弄清楚“中间”直方图(来自过滤器的 256x1 像素图像)如何包含实际的直方图信息,即使除最后一个像素之外的所有像素始终为 (0, 0, 0, 0)。

最佳答案

我认为代码中的 [image bitmapImageRepresentation] 是一个本地类别方法,大致相当于 (NSBitmapImageRep *)image.representations[0]?否则,首先确保您获得正确的输入。

接下来,您似乎将 ciImage.extent 的原始输出传递到过滤器参数中 - 假设该参数需要一个 CIVector 对象而不是 CGRect 结构,您可能在运行时中断了过滤器的输入。您可以通过使用基于字典的过滤器方法 filterWithName:withInputParametersimageByApplyingFilter:withInputParameters: 获得对此类问题更有用的诊断 - 这样,如果您尝试通过nil 作为过滤器键或传递不正确的对象,您将收到编译时错误。后者为您提供了一种直接从输入图像到输出图像或链式过滤器的简单方法,无需创建中间的 CIFilter 对象并需要在每个对象上设置输入图像。

相关提示:您传递的大多数参数都是这些过滤器的默认值,因此您可以仅传递您需要的值:

CIImage *hist = [inputImage imageByApplyingFilter:@"CIAreaHistogram"
withInputParameters:@{ @"inputCount": @256 }];
CIImage *outputImage = [hist imageByApplyingFilter:@"CIHistogramDisplayFilter"
withInputParameters:nil];

最后,您可能仍然会从 CIHistogramDisplayFilter 中获得几乎全灰色图像,具体取决于您的输入图像的外观,因为所有直方图箱都可能具有非常小的酒吧。我得到了 Lenna 的以下信息:

small bars histogram

增加 kCIInputScaleKey 的值可以帮助解决这个问题。

<小时/>

此外,您不需要通过 CGImage 来从 CIImageNSImage — 创建一个 NSCIImageRep 相反,当需要渲染图像以进行显示/输出时,AppKit 将在幕后自动管理 CIContext

// input from NSImage
NSBitmapImageRep *inRep = [nsImage bitmapImageRepresentation];
CIImage *inputImage = [[CIImage alloc] initWithBitmapImageRep:inRep];

CIImage *outputImage = // filter, rinse, repeat

// output to NSImage
NSCIImageRep *outRep = [NSCIImageRep imageRepWithCIImage: outputImage];
NSImage *outNSImage = [[NSImage alloc] init];
[outNSImage addRepresentation: outRep];

关于objective-c - NSImage 的 CIAreaHistogram/CIHistogramDisplayFilter 工作示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40222778/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com