Насыщение CIImage с использованием CIFilters, возможно ли это?

Я работаю с объектом CIImage, пытаясь получить значение насыщенности. Но я не могу найти способ получить насыщенность изображения, по крайней мере, с помощью CIFilters, доступных в OS X.
Можно ли получить насыщенность CIImage с помощью стандартных CIFilters?


person Kibernetik    schedule 05.10.2012    source источник


Ответы (3)


Взгляните на фильтр CIColorControls. С помощью этого фильтра можно настроить насыщенность, яркость и контрастность изображения.

Для вычисления насыщенности этот фильтр выполняет линейную интерполяцию между изображением в градациях серого (насыщенность = 0,0) и исходным изображением (насыщенность = 1,0). Фильтр поддерживает экстраполяцию: для значений больше 1,0 он увеличивает насыщенность.

Пример:

CIFilter *colorControlsFilter = [CIFilter filterWithName:@"CIColorControls"];
[colorControlsFilter setDefaults];
[colorControlsFilter setValue:sourceImage forKey:@"inputImage"];
[colorControlsFilter setValue:[NSNumber numberWithFloat:1.0] forKey:@"inputSaturation"];
[colorControlsFilter setValue:[NSNumber numberWithFloat:0.2] forKey:@"inputBrightness"];
[colorControlsFilter setValue:[NSNumber numberWithFloat:1.0] forKey:@"inputContrast"];

CIImage *outputImage = [colorControlsFilter valueForKey:@"outputImage"];


CIColorControls ссылка здесь.
▸ Все фильтры CIFilter здесь .

person Justin Boo    schedule 05.10.2012
comment
Да, Джастин, таким образом можно изменить или установить желаемую насыщенность. Но мне нужно извлечь насыщенность из CIImage как отдельное изображение в градациях серого. - person Kibernetik; 06.10.2012

Вы не можете сделать это с помощью встроенного CIFilter, но вы можете довольно просто написать код. Я не дам вам полную реализацию, но я могу дать вам cikernel, который сделает эту работу:

vec4 rgbToHsv(vec4 rgb) {
    float x = min(rgb.r, min(rgb.g, rgb.b));
    float v = max(rgb.r, max(rgb.g, rgb.b));
    float f = (rgb.r == x) ? rgb.g - rgb.b : ((rgb.g == x) ? rgb.b - rgb.r : rgb.r - rgb.g);
    float i = (rgb.r == x) ? 3.0 : ((rgb.g == x) ? 5.0 : 1.0);
    float h = i - (f / (v - x));
    float s = (v - x) / v;
    return (v == x) ? vec4(-1, 0, v, rgb.a) : vec4(h, s, v, rgb.a);
}

kernel vec4 saturationToGrayscale(sampler image) {
    vec4 color = sample(image, samplerCoord(image));
    vec4 hsv = rgbToHsv(color);
    return premultiply(vec4(vec3(hsv.g), color.a));
}

Функция rgbToHsv взята из блога Энди Финнелла

Выходным результатом является изображение в градациях серого, где белый означает насыщенность == 1,0, а черный означает насыщенность == 0,0. Вы можете отменить это, используя «1.0-hsv.g» вместо «hsv.g» в возвращаемом аргументе. Вы также можете получить оттенок и значение, используя соответственно hsv.r и rsv.b.

Создание CIFilter остается за вами. Взгляните на Создание пользовательских фильтров сделать это. Приведенный выше код находится в файле .cikernel.

person Pyroh    schedule 28.01.2013

Вы можете настроить насыщенность изображения RGB, преобразовав его в YpCbCr и изменив значения cb и cr. Accelerate.vimage может сделать это преобразование за вас, и у Apple есть пример проекта кода, в котором обсуждается именно эта тема здесь.

Вы можете обернуть операции vImage в CIImageProcessorKernel, чтобы сделать их доступными для Core Image. Опять же, у Apple есть статья, объясняющая, как это сделать здесь.

Надеюсь, это поможет,

Саймон

person Simon Gladman    schedule 26.11.2018