我正在尝试使用Core Image过滤器在Mac应用程序中为图像添加一些颜色校正.首先,我正在考虑允许自定义白平衡,从图像中删除一个演员.它看起来就像CIWhitePointAdjust我正在寻找的那样,但在尝试之后,我不确定我是否使用它错了,或者它是否做不到我想的.
从这张图片开始,随着年龄变黄,右边缘有一条白色的细条:

我应用过滤器,如下所示:
NSColor *whiteSample = // Chosen from the speech bubble's background
CIColor *whiteInputColor = [[CIColor alloc] initWithColor:whiteSample];
layer.filters = @[
    [CIFilter filterWithName:@"CIWhitePointAdjust"
         withInputParameters:@{kCIInputColorKey: whiteInputColor}]
];
并获得此图像:

请注意,它看起来比原始颜色更暗更黄(与我想要的效果相反).我一直期待一种效果更像是在Photoshop中使用自动颜色,如下所示:

我使用CIWhitePointAdjust不正确,还是这项工作的错误工具?如果另一个过滤器或过滤器组合可以更好地工作,我很想知道.
由于我正在操作已经存在于CALayer对象中的图像,因此Core Image过滤器看起来确实是正确的选择,但如果这只能通过其他方式实现,我对此持开放态度.
更新
信号处理站点上一个有用的答案给出了我正在尝试实现的名称.从广义上讲,它被称为直方图均衡.我试图弄清楚是否有办法使用Core Image过滤器执行该过程,到目前为止,它看起来并不太有希望(没有我自己编写).
好的,我想我已经钉好了!这是我从/sf/answers/2131292901/和一些胶合剂弄到的东西:
@import Accelerator;
// I haven't yet found a way to do it within Core Image
// use this when you need to CIImage* -> CGImageRef
CIImage *ciImage = [CIImage imageWithCGImage:cgImage];
...
// use this when you need to CGImageRef -> CIImage*
CIContext* context = [[CIContext alloc] init];
CGImageRef cgImage = [context createCGImage:ciImage fromRect:ciImage.extent];
...
// the algorithm itself, which uses vImage and has to convert to/from it via CGImage
CGImageRef CreateEqualisedCGImageFromCGImage(CGImageRef original)
{
    vImage_Error err;
    vImage_Buffer _img;
    vImage_CGImageFormat format = {
        .bitsPerComponent = 8,
        .bitsPerPixel = 32,
        .colorSpace = NULL,
        .bitmapInfo = (CGBitmapInfo)kCGImageAlphaFirst,
        .version = 0,
        .decode = NULL,
        .renderingIntent = kCGRenderingIntentDefault,
    };
    CGFloat width = CGImageGetWidth(original);
    CGFloat height = CGImageGetHeight(original);
    vImage_Buffer _dstA, _dstR, _dstG, _dstB;
    err = vImageBuffer_InitWithCGImage(&_img, &format, NULL, original, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageBuffer_InitWithCGImage error: %ld", err);
    err = vImageBuffer_Init( &_dstA, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageBuffer_Init (alpha) error: %ld", err);
    err = vImageBuffer_Init( &_dstR, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageBuffer_Init (red) error: %ld", err);
    err = vImageBuffer_Init( &_dstG, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageBuffer_Init (green) error: %ld", err);
    err = vImageBuffer_Init( &_dstB, height, width, 8 * sizeof( uint8_t ), kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageBuffer_Init (blue) error: %ld", err);
    err = vImageConvert_ARGB8888toPlanar8(&_img, &_dstA, &_dstR, &_dstG, &_dstB, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageConvert_ARGB8888toPlanar8 error: %ld", err);
    err = vImageEqualization_Planar8(&_dstR, &_dstR, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageEqualization_Planar8 (red) error: %ld", err);
    err = vImageEqualization_Planar8(&_dstG, &_dstG, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageEqualization_Planar8 (green) error: %ld", err);
    err = vImageEqualization_Planar8(&_dstB, &_dstB, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageEqualization_Planar8 (blue) error: %ld", err);
    err = vImageConvert_Planar8toARGB8888(&_dstA, &_dstR, &_dstG, &_dstB, &_img, kvImageNoFlags);
    if (err != kvImageNoError)
        NSLog(@"vImageConvert_Planar8toARGB8888 error: %ld", err);
    err = vImageContrastStretch_ARGB8888( &_img, &_img, kvImageNoError );
    if (err != kvImageNoError)
        NSLog(@"vImageContrastStretch_ARGB8888 error: %ld", err);
    free(_dstA.data);
    free(_dstR.data);
    free(_dstG.data);
    free(_dstB.data);
    CGImageRef result = vImageCreateCGImageFromBuffer(&_img, &format, NULL, NULL, kvImageNoFlags, &err);
    if (err != kvImageNoError)
        NSLog(@"vImageCreateCGImageFromBuffer error: %ld", err);
    free(_img.data);
    return result;
}
该解决方案的优点全在于/sf/users/331473831/,但是对于基于图像的解决方案,我已经看了很长时间没有成功(与该问题中讨论的视频处理相反) )我认为这样的现成答复是有意义的。在OS X或iOS上寻找“自动水平”功能无济于事,我希望这对其他人可能有用。
小智 0
尝试使用autoAdjustmentFilters 或 autoAdjustmentFiltersWithOptions获取可能的过滤器列表...可能是后者,以便您可以排除需要面部检测的过滤器(如果您计划自动调整卡通扫描)。