Please note: 这适用于在Mac OSX上运行的Cocoa命令行应用程序,并且 NOT an iOS app
我在尝试理解Apple为 CISpotColor 过滤器(使用 CIFilter )提供的Limited Documentation时遇到了一些麻烦 .
TL DR;
1)是否有更多关于CIFilter遗漏的文档,特别是CISpotColor?
2)考虑到我想要实现的目标(如下图所示,但简要说明:用白色替换所有不“看起来红”的东西,并将“看起来很红(ish)”的所有东西强制为纯红色或简单的黑色) ,CISpotColor是我应该使用的正确过滤器吗?
3)如果没有,你建议使用什么过滤器(或者我应该尝试编写自定义过滤器?)
4)如果CISSpotColor是正确的过滤器,我应该使用什么参数来实现我想要实现的目标 . 如果我需要使用CISpotColor CIFilter的几个通道,那很好,我不指望你为我编码,只是指出我正确的方向 .
以上问题的更多细节和背景:
link above给出了一个参数列表,一些默认值,以及图片之前和之后的示例,但没有在图像之后生成样本的示例代码,也没有解释参数实际意味着什么,或者它们的有效范围是什么 .
老实说,我不完全确定CISpotColor是否是我所追求的过滤器,除了它的名称和句子“ Replaces one or more color ranges with spot colors ”之外,没有解释它是如何做到的 .
因为它似乎描述了我所追求的过滤器,所以我选择它作为一个起点,让我以这种方式处理过滤器 .
Input picture (a frame from a video)
Desired output (option 1 - solid red - created using GIMP)
Desired output (option 2 - solid black - also created using GIMP)
What I am getting with my code (see below for listing)
这接近我所需要的,但它似乎没有考虑到原始图像中灰色或“白色”的区域具有相似数量的红色,绿色和蓝色,而不是主要是红色的事实 . 这将使它“看起来红” . 如果它过滤掉你在右下角看到的区域,我可以使用它,这显然只是包括在内,因为那里有一些红色像素(以及一些绿色和蓝色,使其在原始时通常为灰色) .
Here is the complete "main.m" for the cocoa command line app (Mac OSX)
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <AppKit/AppKit.h>
#import <QuartzCore/QuartzCore.h>
@interface NSImage(saveAsJpegWithName)
- (void) saveAsPNGWithName:(NSString*) fileName;
- (NSImage*) filterEverythingButRed ;
@end
@implementation NSImage(saveAsJpegWithName)
- (void) saveAsPNGWithName:(NSString*) fileName
{
NSData *imageData = [self TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
NSDictionary *imageProps = nil;
imageData = [imageRep representationUsingType:NSPNGFileType properties:imageProps];
[imageData writeToFile:fileName atomically:NO];
}
-(NSImage*) filterEverythingButRed {
CIImage *inputImage = [[CIImage alloc] initWithData:[self TIFFRepresentation]];
CIFilter *hf = [CIFilter filterWithName:@"CISpotColor"];
[hf setDefaults];
[hf setValue:inputImage forKey:@"inputImage"];
[hf setValue:[CIColor colorWithRed:1.0 green:0.0 blue:0.0] forKey: @"inputCenterColor1"];
[hf setValue:[CIColor colorWithRed:1.0 green:0.0 blue:0.0] forKey: @"inputReplacementColor1"];
[hf setValue:[NSNumber numberWithFloat:0.1] forKey: @"inputCloseness1"];
[hf setValue:[NSNumber numberWithFloat:1.0] forKey: @"inputContrast1"];
CIImage *outputImage = [hf valueForKey: @"outputImage"];
NSImage *resultImage = [[NSImage alloc] initWithSize:[outputImage extent].size];
NSCIImageRep *rep = [NSCIImageRep imageRepWithCIImage:outputImage];
[resultImage addRepresentation:rep];
return resultImage;
}
@end
int main(int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (argc == 1) {
NSString * appname = [NSString stringWithFormat: @"%s", argv[0]];
NSLog(@"Usage: %@ filename", appname);
} else {
NSString * filename = [NSString stringWithFormat: @"%s", argv[1]];
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:filename]) {
NSLog(@"opening file:%@", filename);
NSImage *img = [[NSImage alloc] initWithContentsOfFile:filename];
[[img filterEverythingButRed]
saveAsPNGWithName:[[filename stringByDeletingPathExtension] stringByAppendingString:@"-red.png"]];
} else {
NSLog(@"file not found:%@", filename);
}
}
[pool release];
return 0;
}
2 回答
CISpotColor
基本上做了四种颜色操作:用
inputReplacementColor1
替换inputCenterColor1
附近的所有颜色 .用
inputReplacementColor2
替换inputCenterColor2
附近的所有颜色 .用
inputReplacementColor3
替换inputCenterColor3
附近的所有颜色 .用白色替换其他所有东西 .
默认情况下,输入颜色设置为各种偏红/粉红色调 . 您可以通过在构造它之后检查代码中的那些过滤器值并调用
setDefaults
来找到这些 - 但为了便于说明,这里是Core Image Fun House示例代码应用程序的屏幕截图中的所有默认值:使用默认选项应用过滤器可以获得以下结果:
请注意,红色环(您试图成为图像中唯一剩余元素的部分)看起来像默认
inputReplacementColor3
,右下方的亮起区域看起来像默认inputReplacementColor2
...就像它们在your output image . 那个's because you' ve只配置了第一对中心/替换颜色,你已经将其他两个颜色保留为红色/粉红色默认值 .如果要禁用第二和第三种颜色替换,请将其Closeness参数向下调整为0.0和/或将其Contrast参数调高至1.0 . 为安全起见,您还可以将其中心颜色设置为图像中未显示的内容 . 在您的测试图像中,我发现仅仅调低Closeness就足够了:
这得到以下输出:
顺便说一下,像这样的专色替换是一种简单形式的Color LookUp Table(CLUT)操作,它由CIColorCube过滤器实现 . 如果您希望能够在
CISpotColor
提供的范围内微调颜色替换,那么颜色立方体选项可能是一个不错的选择 . 有一个关于将它用于绿屏效果的教程in Apple's programming guide .TLDR:
为所有过滤器参数设置适当的值,而不仅仅是前几个,或者其他默认值可能会执行您不期望的事情 . 将
inputCloseness2
和inputCloseness3
设置为零并保留其他所有默认值(但对于您已设置的input...1
参数)似乎适用于您的测试图像 .进行实时测试过滤器的环境确实可以帮助您微调参数(并确保默认值是您所期望的) . Core Image Fun House非常棒 .
你是对的,仍然没有文件 . 例如,使用“核心图像娱乐屋”作为您的信息来源不会给您一个指示,您输入点1中的颜色,以及输入点2中的哪种颜色非常重要...切换它们会给你一个结果差异很大,我在这个特殊的过滤器中发现了更多的问题 . 就像某些参数的“最大”值一样,代码更像是你所谓的“指南”而非实际规则 . :)使用“有趣的房子”作为一个来源,将让你走下一个有大约10个出口的兔子洞,没有迹象告诉你这些出口在哪里 .
这里有一些笔记,我把疯狂的数字扔进这个过滤器,看看什么“卡在墙上” . (如果有人选择,需要更多)