CIImage (IOS): добавление свертки 3x3 после монохромного фильтра каким-то образом восстанавливает цвет

Я конвертирую ciimage в монохромный, обрезаю с помощью CICrop и запускаю sobel для обнаружения краев, раздел #if внизу используется для отображения результата

CIImage *ci = [[CIImage alloc] initWithCGImage:uiImage.CGImage];

CIImage *gray = [CIFilter filterWithName:@"CIColorMonochrome" keysAndValues:
      @"inputImage", ci, @"inputColor", [[CIColor alloc] initWithColor:[UIColor whiteColor]],
      nil].outputImage;



CGRect rect = [ci extent];
rect.origin = CGPointZero;

CGRect cropRectLeft = CGRectMake(0, 0, rect.size.width * 0.2, rect.size.height);
CIVector *cropRect = [CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width* 0.2 W:rect.size.height];
CIImage *left = [gray imageByCroppingToRect:cropRectLeft];

CIFilter *cropFilter = [CIFilter filterWithName:@"CICrop"];

[cropFilter setValue:left forKey:@"inputImage"];
[cropFilter setValue:cropRect forKey:@"inputRectangle"];

// The sobel convoloution will produce an image that is 0.5,0.5,0.5,0.5 whereever the image is flat
// On edges the image will contain values that deviate from that based on the strength and
// direction of the edge
const double g = 1.;
const CGFloat weights[] = { 1*g, 0, -1*g,
    2*g, 0, -2*g,
    1*g, 0, -1*g};
left = [CIFilter filterWithName:@"CIConvolution3X3" keysAndValues:
      @"inputImage", cropFilter.outputImage,
      @"inputWeights", [CIVector vectorWithValues:weights count:9],
      @"inputBias", @0.5,
      nil].outputImage;

#define VISUALHELP 1
#if VISUALHELP
CGImageRef imageRefLeft = [gcicontext createCGImage:left fromRect:cropRectLeft];
CGContextDrawImage(context, cropRectLeft, imageRefLeft);
CGImageRelease(imageRefLeft);
#endif

Теперь всякий раз, когда свертка 3x3 не является частью конвейера ciimage, часть изображения, на которой я запускаю обнаружение краев, отображается серым, но всякий раз, когда постфикс CIConvolution3X3 является частью конвейера обработки, цвета волшебным образом возвращаются. Это происходит независимо от того, использую ли я префикс CIColorMonochrome или CIPhotoEffectMono для удаления цвета. Любые идеи, как сохранить цвет на всем пути к нижней части конвейера? спасибо

UPD: неудивительно, что используется сырое пользовательское монохромное ядро, такое как это.

kernel vec4 gray(sampler image)
{
    vec4 s = sample(image, samplerCoord(image));
    float r = (s.r * .299 + s.g * .587 + s.b * 0.114) * s.a;
    s = vec4(r, r, r, 1);
    return s;
}

вместо использования стандартных монофильтров от Apple приводит к той же проблеме с возвращением цвета, когда свертка 3x3 является частью моего конвейера ci


person Anton Tropashko    schedule 28.10.2014    source источник


Ответы (2)


Эта проблема заключается в том, что операции свертки CI (например, CIConvolution3X3, CIConvolution5X5 и CIGaussianBlur) работают со всеми четырьмя каналами входного изображения. Это означает, что в вашем примере кода результирующий альфа-канал будет 0,5, тогда как вы, вероятно, хотите, чтобы он был 1,0. Попробуйте добавить простое ядро ​​​​после свертки, чтобы вернуть альфу к 1.

person David Hayward    schedule 25.01.2015

в продолжение: я отказался от coreimage для этой задачи. кажется, что использование двух экземпляров CIFilter или CIKernel вызывает конфликт. Кто-то где-то во внутренностях coreimage, кажется, неправильно манипулирует состоянием gles, и, таким образом, обратное проектирование того, что пошло не так, обходится дороже, чем использование чего-то другого, кроме основного образа (с пользовательскими фильтрами ci, которые в любом случае работают только на ios8) gpuimage кажется не таким глючным и проще для обслуживания/отладки (без моего участия)

person Anton Tropashko    schedule 05.11.2014
comment
Похоже на серьезный баг. Вы подали заявку в Apple? - person rickster; 03.12.2014
comment
нет. Я не зарегистрировал его (у меня есть 3 ошибки, 2 из которых немедленно игнорируются Apple). Вы можете подать его. - person Anton Tropashko; 09.02.2015