我正在iOS中绘制几个灰度图像。灰度图像的值具有最小值和最大值,即范围为[41,244]的8位值。

我想更改最小值或最大值。我想知道如何在this list中设置过滤器以更改最小值,以及如何在this list中设置过滤器以更改最大值?

也许下面的绘画会很好看:

[1。读取原始灰度数据]-> [2。创建CGImageRef]-> [3。在GPU中加载参考]

现在,在iOS 6中可以实时在GPU中应用过滤器。对我来说,在1或2上进行操作非常慢,因为在一秒钟内我应该绘制100张图像。所以我需要在GPU中使用CIFilter。我知道如何过滤图像。但是什么过滤器可以完成我的工作?

一些示例代码对我有好处。

最佳答案

CIToneCurve应该适合这种事情。

- (UIImage*) applyToneCurveToImage:(UIImage*)image
{
    CIContext* context = self.context;
    CIImage* ciImage = [[CIImage alloc] initWithImage:image];

    CIFilter*   filter =
        [CIFilter filterWithName:@"CIToneCurve"
                   keysAndValues:
                kCIInputImageKey, ciImage,
                  @"inputPoint0",[CIVector vectorWithX:0.00 Y:0.3]
                 ,@"inputPoint1",[CIVector vectorWithX:0.25 Y:0.4]
                 ,@"inputPoint2",[CIVector vectorWithX:0.50 Y:0.5]
                 ,@"inputPoint3",[CIVector vectorWithX:0.75 Y:0.6]
                 ,@"inputPoint4",[CIVector vectorWithX:1.00 Y:0.7]
                 ,nil];

    CIImage* result = [filter valueForKey:kCIOutputImageKey];

    CGImageRef cgImage = [context createCGImage:result
                                            fromRect:[result extent]];
    UIImage* filteredImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return filteredImage;
}
self.context可以是CPU或GPU(EAGL)上下文。这些点描述了色调曲线。 X是输入值,Y是输出值。在此示例中,我们减小了斜率,因此减小了对比度。您也可以使斜率保持不变,但要消除极端,以减小最大值和最小值。

以下是在iPad mini上处理100张图像的一些测量结果(每个设置平均四个读数)。您会发现GPU并不是万能的,大约60%至65%的时间都集中在移动图像数据上。这些示例以UIImage开头和结尾。我用CGImage得到了非常相似的结果。
                              57x57px png  640x800px jpeg
 UIImage->CIImage->UIImage (no filtering)
                       CPU    0.57s        2.83s
                       GPU    0.36s        2.83s
 UIImage->CIImage->CIFilter->UIImage
                       CPU    0.75s        4.38s
                       GPU    0.58s        4.32s

更新

对于超出窗口范围的输入的零值的Window and Level调整,您想要实现以下功能:
CGFloat w;  //window
CGFloat l;  //level

              @"inputPoint0",[CIVector vectorWithX:0.0   Y:0.0]
             ,@"inputPoint1",[CIVector vectorWithX:l-w/2 Y:0.0]
             ,@"inputPoint2",[CIVector vectorWithX:l+w/2 Y:1.0]
             ,@"inputPoint3",[CIVector vectorWithX:l+w/2 Y:0.0]
             ,@"inputPoint4",[CIVector vectorWithX:1.0   Y:0.0]

实际上,这是行不通的。这些点描述了样条曲线,并且在方向急剧变化(例如b-c-d)时效果不佳。 (另外,点c和d(2和3)不能共享相同的x值,因此在任何情况下都必须稍微增加一点,以使d.x = c.x * 1.01)

如果使用多步过滤器,则可以得到结果。第一个过滤器适当地使用了CIToneCurve(这是正确的窗口/级别算法,而没有尝试将最大级别降低到零)。
        CIFilter*   filter =
        [CIFilter filterWithName:@"CIToneCurve"
                   keysAndValues:
                kCIInputImageKey, ciImage,
              @"inputPoint0",[CIVector vectorWithX:0.0   Y:0.0]
             ,@"inputPoint1",[CIVector vectorWithX:l-w/2 Y:0.0]
             ,@"inputPoint2",[CIVector vectorWithX:l     Y:0.5]
             ,@"inputPoint3",[CIVector vectorWithX:l+w/2 Y:1.0]
             ,@"inputPoint4",[CIVector vectorWithX:1.0   Y:1.0]

我们将复制过滤器,因为在最后一步中将再次需要它:
        filter2 = [filter copy];

应用CIColorControls滤镜以最大化结果的对比度和亮度
        filter = [CIFilter filterWithName:@"CIColorControls"
                            keysAndValues:kCIInputImageKey,
                    [filter valueForKey:kCIOutputImageKey], nil];

        [filter setValue:[NSNumber numberWithFloat:-1]
                  forKey:@"inputBrightness"];
        [filter setValue:[NSNumber numberWithFloat:4]
                  forKey:@"inputContrast"];

现在分装到1位调色板
        filter = [CIFilter filterWithName:@"CIColorPosterize"
                             keysAndValues:kCIInputImageKey,
                     [filter valueForKey:kCIOutputImageKey], nil];

        [filter setValue:@2 forKey:@"inputLevels"];

反转结果
        filter = [CIFilter filterWithName:@"CIColorInvert"
                            keysAndValues:kCIInputImageKey,
                    [filter valueForKey:kCIOutputImageKey], nil];

现在,我们将此结果用作窗口/水平图像的遮罩,以便所有最大白色水平都降低为黑色。
        filter = [CIFilter filterWithName:@"CIDarkenBlendMode"
                            keysAndValues:kCIInputImageKey,
                    [ filter valueForKey:kCIOutputImageKey], nil];

        [filter setValue:[filter2 valueForKey:kCIOutputImageKey]
                  forKey:@"inputBackgroundImage"];

原版的

filter1 CIToneCurve
filter2 CIColorControls
filter3 CIColorPosterize
filter4 CIColorInvert
filter5 CIDarkenBlendMode
如果看一下布拉德·拉尔森(Brad Larson)的 GPUImage ,您会发现GPUImageLuminanceThresholdFilter将更好地替换过滤器2-> 5。

关于objective-c - 如何在Core镜像中通过CIFilter更改最小值或最大值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16185424/

10-14 23:35
查看更多