卷积矩阵锐化滤波器

时间:2016-05-30 15:50:30

标签: objective-c convolution imagefilter

我试图为图像实现锐化卷积矩阵滤波器。为此我创建矩阵3x3。也许我做了一些错误的配方?我也试过其他锐化矩阵,但它没有帮助。颜色值可能大于255或小于零,所以我决定对此给出一些限制(0 255)。这是正确的解决方案吗?

static const int filterSmallMatrixSize = 3;
static const int sharpMatrix[3][3] = {{-1, -1, -1},{-1, 9, -1},{-1, -1, -1}};

一些定义

#define Mask8(x) ( (x) & 0xFF )
#define R(x) ( Mask8(x) )
#define G(x) ( Mask8(x >> 8 ) )
#define B(x) ( Mask8(x >> 16) )
#define A(x) ( Mask8(x >> 24) )
#define RGBAMake(r, g, b, a) ( Mask8(r) | Mask8(g) << 8 | Mask8(b) << 16 | Mask8(a) << 24 )

和算法

- (UIImage *)processSharpFilterUsingPixels:(UIImage *)inputImage
{
    UInt32 *inputPixels;
    CGImageRef inputCGImage = [inputImage CGImage];
    NSUInteger inputWidth = CGImageGetWidth(inputCGImage);
    NSUInteger inputHeight = CGImageGetHeight(inputCGImage);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    NSUInteger bytesPerPixel = 4;
    NSUInteger bitsPerComponent = 8;
    NSUInteger inputBytesPerRow = bytesPerPixel * inputWidth;
    inputPixels = (UInt32 *)calloc(inputHeight * inputWidth, sizeof(UInt32));
    CGContextRef context = CGBitmapContextCreate(inputPixels, inputWidth, inputHeight,
                                                 bitsPerComponent, inputBytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGContextDrawImage(context, CGRectMake(0, 0, inputWidth, inputHeight), inputCGImage);

    for (NSUInteger j = 1; j < inputHeight - 1; j++)
    {
        for (NSUInteger i = 1; i < inputWidth - 1; i++)
        {
            Float32 newRedColor = 0;
            Float32 newGreenColor = 0;
            Float32 newBlueColor = 0;
            Float32 newA = 0;

            for (int filterMatrixI = 0 ; filterMatrixI < filterSmallMatrixSize ; filterMatrixI ++)
            {
                for (int filterMatrixJ = 0; filterMatrixJ < filterSmallMatrixSize; filterMatrixJ ++)
                {
                    UInt32 * currentPixel = inputPixels + ((j + filterMatrixJ - 1) * inputWidth) + i + filterMatrixI - 1;
                    int color = *currentPixel;
                    newRedColor += (R(color) * sharpMatrix[filterMatrixI][filterMatrixJ]);
                    newGreenColor += (G(color) * sharpMatrix[filterMatrixI][filterMatrixJ]);
                    newBlueColor += (B(color)* sharpMatrix[filterMatrixI][filterMatrixJ]);
                     newA += (A(color) * sharpMatrix[filterMatrixI][filterMatrixJ]);
                }
            }
            int r = MAX( MIN((int)newRedColor,255), 0);
            int g = MAX( MIN((int)newGreenColor,255), 0);
            int b = MAX( MIN((int)newBlueColor,255), 0);
            int a = MAX( MIN((int)newA,255), 0);
            UInt32 *currentMainImagePixel = inputPixels + (j * inputWidth) + i;
            *currentMainImagePixel = RGBAMake(r,g,b,a);
        }
    }

    CGImageRef newCGImage = CGBitmapContextCreateImage(context);
    UIImage * processedImage = [UIImage imageWithCGImage:newCGImage];

    CGColorSpaceRelease(colorSpace);
    CGContextRelease(context);
    free(inputPixels);

    return processedImage;
}

结果我有this

1 个答案:

答案 0 :(得分:2)

考虑这些是图像中间的像素:

|_|_|_|_|
|_|_|_|_|
|_|_|_|_|
|_|_|_|_|

由于您正在更新图像,这就是它在锐化周期中的某个位置:

|u|u|u|u|
|u|u|u|u|
|u|c|_|_|
|_|_|_|_|

其中u代表更新的像素,c代表当前。所以他的新颜色取决于环绕像素的颜色,其中一半来自已经锐化的图像,一半来自原点。要修复它,我们需要原始图像像素的副本:

...
CGContextDrawImage(context, CGRectMake(0, 0, inputWidth, inputHeight), inputCGImage);

UInt32 *origPixels = calloc(inputHeight * inputWidth, sizeof(UInt32));
memcpy(origPixels, inputPixels, inputHeight * inputWidth * sizeof(UInt32));

for (NSUInteger j = 1; j < inputHeight - 1; j++) {
...

现在我们只需更改一行即可从原始图像中获取当前像素

//changed inputPixels -> origPixels
UInt32 * currentPixel = origPixels + ((j + filterMatrixJ - 1) * inputWidth) + i + filterMatrixI - 1;

Here are some与未更新过滤器相比如何工作的示例(链接是dropbox,对不起)。我尝试过不同的矩阵,对我来说最好的是在某处

const float sharpMatrix[3][3] = {{-0.3, -0.3, -0.3},{-0.3, 3.4, -0.3},{-0.3, -0.3, -0.3}}

另外,我需要注意这种保持原始图像的方式不是最佳的。我的修复基本上消耗了大量的内存。通过只保留两行像素可以轻松完成,我相信还有更好的方法。