Я работаю с объектом CIImage, пытаясь получить значение насыщенности. Но я не могу найти способ получить насыщенность изображения, по крайней мере, с помощью CIFilters, доступных в OS X.
Можно ли получить насыщенность CIImage с помощью стандартных CIFilters?
Насыщение CIImage с использованием CIFilters, возможно ли это?
Ответы (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 здесь .
Вы не можете сделать это с помощью встроенного 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.
Вы можете настроить насыщенность изображения RGB, преобразовав его в YpCbCr и изменив значения cb
и cr
. Accelerate.vimage может сделать это преобразование за вас, и у Apple есть пример проекта кода, в котором обсуждается именно эта тема здесь.
Вы можете обернуть операции vImage в CIImageProcessorKernel
, чтобы сделать их доступными для Core Image. Опять же, у Apple есть статья, объясняющая, как это сделать здесь.
Надеюсь, это поможет,
Саймон