iPhone图像处理 - 矩阵卷积

时间:2010-04-18 22:06:53

标签: iphone

我正在iPhone上实现矩阵卷积模糊。以下代码将作为blur函数的参数提供的UIImage转换为CGImageRef,然后将RGBA值存储在标准C char数组中。

    CGImageRef imageRef = imgRef.CGImage;
int width = imgRef.size.width;
int height = imgRef.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *pixels = malloc((height) * (width) * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * (width);
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(pixels, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);

然后将存储在像素阵列中的像素值进行卷积,并存储在另一个阵列中。

unsigned char *results = malloc((height) * (width) * 4);

最后,将这些增强的像素值更改回CGImageRef,转换为UIImage,并使用以下代码在函数末尾返回。

    context = CGBitmapContextCreate(results, width, height,
                                bitsPerComponent, bytesPerRow, colorSpace,
                                kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGImageRef finalImage = CGBitmapContextCreateImage(context);


UIImage *newImage  = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGImageRelease(finalImage);

NSLog(@"edges found");
free(results);
free(pixels);
CGColorSpaceRelease(colorSpace);


return newImage;

一次完美无缺。然后,一旦图像再次通过滤波器,则返回表示不存在的输入像素值的非常奇怪的,前所未有的像素值。有没有理由为什么这应该第一次工作,但之后不是? Beneath是整个功能。

    -(UIImage*) blur:(UIImage*)imgRef {
CGImageRef imageRef = imgRef.CGImage;
int width = imgRef.size.width;
int height = imgRef.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *pixels = malloc((height) * (width) * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * (width);
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(pixels, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);


height = imgRef.size.height;
width = imgRef.size.width;
float matrix[] = {1,1,1,1,1,1,1,1,1};
float divisor = 9;
float shift = 0;


unsigned char *results = malloc((height) * (width) * 4);


for(int y = 1; y < height; y++){
    for(int x = 1; x < width; x++){
        float red = 0;
        float green = 0;
        float blue = 0;
        int multiplier=1;

        if(y>0 && x>0){
        int index = (y-1)*width + x;
        red = matrix[0]*multiplier*(float)pixels[4*(index-1)] +
        matrix[1]*multiplier*(float)pixels[4*(index)] +
        matrix[2]*multiplier*(float)pixels[4*(index+1)];
        green = matrix[0]*multiplier*(float)pixels[4*(index-1)+1] +
        matrix[1]*multiplier*(float)pixels[4*(index)+1] +
        matrix[2]*multiplier*(float)pixels[4*(index+1)+1];
        blue = matrix[0]*multiplier*(float)pixels[4*(index-1)+2] +
        matrix[1]*multiplier*(float)pixels[4*(index)+2] +
        matrix[2]*multiplier*(float)pixels[4*(index+1)+2];

        index = (y)*width + x;

        red = red+ matrix[3]*multiplier*(float)pixels[4*(index-1)] +
        matrix[4]*multiplier*(float)pixels[4*(index)] +
        matrix[5]*multiplier*(float)pixels[4*(index+1)];
        green = green + matrix[3]*multiplier*(float)pixels[4*(index-1)+1] +
        matrix[4]*multiplier*(float)pixels[4*(index)+1] +
        matrix[5]*multiplier*(float)pixels[4*(index+1)+1];
        blue = blue + matrix[3]*multiplier*(float)pixels[4*(index-1)+2] +
        matrix[4]*multiplier*(float)pixels[4*(index)+2] +
        matrix[5]*multiplier*(float)pixels[4*(index+1)+2];


        index = (y+1)*width + x;
        red = red+ matrix[6]*multiplier*(float)pixels[4*(index-1)] +
        matrix[7]*multiplier*(float)pixels[4*(index)] +
        matrix[8]*multiplier*(float)pixels[4*(index+1)];
        green = green + matrix[6]*multiplier*(float)pixels[4*(index-1)+1] +
        matrix[7]*multiplier*(float)pixels[4*(index)+1] +
        matrix[8]*multiplier*(float)pixels[4*(index+1)+1];
        blue = blue + matrix[6]*multiplier*(float)pixels[4*(index-1)+2] +
        matrix[7]*multiplier*(float)pixels[4*(index)+2] +
        matrix[8]*multiplier*(float)pixels[4*(index+1)+2];

        red = red/divisor+shift;
        green = green/divisor+shift;
        blue = blue/divisor+shift;

        if(red<0){
            red=0;
        }
        if(green<0){
            green=0;
        }
        if(blue<0){
            blue=0;
        }

        if(red>255){
            red=255;
        }
        if(green>255){
            green=255;
        }
        if(blue>255){
            blue=255;
        }

        int realPos = 4*(y*imgRef.size.width + x);

        results[realPos] = red;
        results[realPos + 1] = green;
        results[realPos + 2] = blue;
        results[realPos + 3] = 1;

            }else {
         int realPos = 4*((y)*(imgRef.size.width) + (x));
         results[realPos] = 0;
         results[realPos + 1] = 0;
         results[realPos + 2] = 0;
         results[realPos + 3] = 1;
         }

    }
}

context = CGBitmapContextCreate(results, width, height,
                                bitsPerComponent, bytesPerRow, colorSpace,
                                kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGImageRef finalImage = CGBitmapContextCreateImage(context);


UIImage *newImage  = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGImageRelease(finalImage);

free(results);
free(pixels);
CGColorSpaceRelease(colorSpace);


return newImage;}

感谢!!!

1 个答案:

答案 0 :(得分:1)

问题是我正在假设alpha值,需要像RGB值那样计算它。