objective-c – 使用CIFilter和CISpotColor正确过滤NSImage / CI
请注意:这适用于在Mac OSX上运行的
Cocoa命令行应用程序,而不是iOS应用程序
我在尝试理解Apple为CISpotColor过滤器提供的Limited Documentation(使用CIFilter)时遇到了一些麻烦. TL DR; 1)是否有更多关于CIFilter遗漏的文档,特别是CISpotColor? 2)考虑到我想要实现的目标(如下图所示,但简要说明:用白色替换所有不“看起来红”的东西,并将“看起来很红(ish)”的所有东西强制为纯红色或简单的黑色),CISpotColor是我应该使用的正确过滤器吗? 3)如果没有,你建议使用什么过滤器(或者我应该尝试编写自定义过滤器?) 4)如果CISSpotColor是正确的过滤器,我应该使用什么参数来实现我想要实现的目标.如果我需要使用CISpotColor CIFilter的几个通道,那很好,我不指望你为我编码,只是指出我正确的方向. 以上问题的更多细节和背景: link above给出了参数列表,一些默认值以及图片之前和之后的示例,但没有示例代码在图像之后生成样本,并且没有解释参数实际意味着什么,或者它们的有效范围是什么. 说实话,我不完全确定CISpotColor是否是我所追求的过滤器,除了它的名称,以及句子“用专色替换一个或多个颜色范围”,没有解释它是如何做的. . 因为它似乎描述了我所追求的过滤器,所以我选择它作为一个起点,让我以这种方式处理过滤器. 输入图片(视频中的帧) 期望的输出(选项1 – 纯红色 – 使用GIMP创建) 期望的输出(选项2 – 纯黑色 – 也使用GIMP创建) 我的代码得到了什么(见下面的列表) 这接近我所需要的,但它似乎没有考虑到原始图像中灰色或“白色”的区域具有相似数量的红色,绿色和蓝色,而不是主要是红色的事实.这将使它“看起来红”.如果它过滤掉你在右下角看到的区域,我可以使用它,这显然只是包括在内,因为那里有一些红色像素(以及一些绿色和蓝色,使其在原始时通常为灰色) . 这是cocoa命令行应用程序(Mac OSX)的完整“main.m” #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; } 解决方法
CISpotColor基本上可以进行四种颜色操作:
>使用inputReplacementColor1替换inputCenterColor1附近的所有颜色. 默认情况下,输入颜色设置为各种偏红/粉红色调.您可以通过在构造它们并调用setDefaults之后在代码中检查这些过滤器值来找到它们 – 但为了便于说明,这里是来自Core Image Fun House示例代码应用程序的屏幕截图中的所有默认值: 使用默认选项应用过滤器可以获得以下结果: 请注意,红色环(您尝试成为图像中唯一剩余元素的部分)看起来像默认的inputReplacementColor3,右下方的亮区看起来像默认的inputReplacementColor2 ……就像它们在your output image.那是因为你只配置了第一对中心/替换颜色,而你已经将其他两个颜色保留为红色/粉红色默认值. 如果要禁用第二和第三种颜色替换,请将其Closeness参数向下调整为0.0和/或将其Contrast参数调高至1.0.为安全起见,您还可以将其中心颜色设置为图像中未显示的内容.在您的测试图像中,我发现仅仅调低Closeness就足够了: 这得到以下输出: 顺便说一句,像这样的专色替换是一种简单形式的Color LookUp Table(CLUT)操作,由 TLDR: >为所有过滤器参数设置适当的值,而不仅仅是前几个,或者其他默认值可能会做您不期望的事情.将inputCloseness2和inputCloseness3设置为零并保留其他所有默认值(但对于您已经设置的输入… 1参数)似乎适用于您的测试图像. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |