开发者

UIImage - implementing an auto levels algorithm

I'd like to implement an "auto levels" option for a UIImage that I am displaying in my iPhone app. Before I try to implement it myself, I was wondering if there are any image processing methods in the APIs 开发者_开发知识库I should be using, for histograms, etc. Or should I just grab the underlying CGImage and process it? (I am new to iPhone dev.)

Thanks

MV


One very easy approach is to use the decode array of a CGImageRef, but this is can only help for an range mapping (no gamma, etc.)

    const CGFloat decode[6] = {blackPoint,whitePoint,blackPoint,whitePoint,blackPoint,whitePoint};

    decodedImage = CGImageCreate(CGImageGetWidth(origImage),
                                CGImageGetHeight(origImage),
                                CGImageGetBitsPerComponent(origImage),
                                CGImageGetBitsPerPixel(origImage),
                                CGImageGetBytesPerRow(origImage),
                                CGImageGetColorSpace(origImage),
                                CGImageGetBitmapInfo(origImage),
                                CGImageGetDataProvider(origImage),
                                decode,
                                YES,
                                CGImageGetRenderingIntent(origImage)
                                );

Where whitePoint is a float between 0.0 and 1.0, that determines which brightness will to mapped to pure white in the output, and blackPoint is also a float, that determines which brightness is mapped to pure black.

The decode array's elements correspond to the components of the colorspace, so this code will only work for RBG images. You can set the components to different white and black values to create a simple color-correction.

You can calculate the whitePoint and the blackPoint with the following function (w/o color correction):

void CalculateAutocorretionValues(CGImageRef image, CGFloat *whitePoint, CGFloat *blackPoint) {
    UInt8* imageData = malloc(100 * 100 * 4);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(imageData, 100, 100, 8, 4 * 100, colorSpace, kCGImageAlphaNoneSkipLast);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(ctx, CGRectMake(0, 0, 100, 100), image);

    int histogramm[256];
    bzero(histogramm, 256 * sizeof(int));

    for (int i = 0; i < 100 * 100 * 4; i += 4) {
            UInt8 value = (imageData[i] + imageData[i+1] + imageData[i+2]) / 3;
            histogramm[value]++;
    }

    CGContextRelease(ctx);
    free(imageData);

    int black = 0;
    int counter = 0;

    // count up to 200 (2%) values from the black side of the histogramm to find the black point
    while ((counter < 200) && (black < 256)) {
            counter += histogramm[black];
            black ++;
    }

    int white = 255;
    counter = 0;

    // count up to 200 (2%) values from the white side of the histogramm to find the white point
    while ((counter < 200) && (white > 0)) {
            counter += histogramm[white];
            white --;
    }

    *blackPoint = 0.0 - (black / 256.0);
    *whitePoint = 1.0 + ((255-white) / 256.0);
}


I don't think there are existing APIs that do image processing, but I'm sure there are third-party libraries out there.


This explains auto-levels (i.e., histogram equalization) really well:

http://www.generation5.org/content/2004/histogramEqualization.asp

They also have Java implementation of the same.


You could try the CImg library... They have histogram and equalize functions on the docs. The equalize() function has pretty decent results, from the sample image. The license is LGPL, which may not be suitable for your project but is compatible with selling on the app store.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜