Reputation: 3028
I am working with CIImage object, trying to get saturation value. But I cannot find the way to get image saturation, at least using CIFilters available in OS X.
Is it possible to get saturation of CIImage using standard CIFilters?
Upvotes: 1
Views: 5718
Reputation: 3643
You can adjust the saturation of an RGB image by converting it to YpCbCr and changing the cb
and cr
values. Accelerate.vimage can do this conversion for you, and Apple has a sample code project discussing that very topic here.
You can wrap vImage operations in a CIImageProcessorKernel
to make them available to Core Image. Again, Apple has an article explaining how to do that here.
Hope that helps,
simon
Upvotes: 0
Reputation: 10198
Take a look at CIColorControls
filter. With this filter it is possible to adjust image's saturation, brightness, and contrast.
To calculate saturation, this filter linearly interpolates between a grayscale image (saturation = 0.0) and the original image (saturation = 1.0). The filter supports extrapolation: For values large than 1.0, it increases saturation.
Example:
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
reference here.
▸ All CIFilters here.
Upvotes: 3
Reputation: 216
You cannot do it using built-in CIFilter but you can code it quite simply. I won't give you full implementation but I can give you the cikernel that'll do the work :
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 function comes from Andy Finnell's blog
Output result is a grayscale image where white means sat == 1.0 and black means sat == 0.0. You can revert this by using "1.0-hsv.g" instead of "hsv.g" in the return argument. You can also retrieve hue and value by using respectively hsv.r and rsv.b.
Making it a CIFilter is left to you. Take a Look at Apple's Creating Custom Filters to do this. The code above takes place in the .cikernel file.
Upvotes: 0